ACM_JAVA(ACM模板)

合集下载

javaacm的竞赛题目

javaacm的竞赛题目

以下是几个Java ACM竞赛的题目示例:
题目名称:最大子数组和
给定一个整数数组,找到具有最大和的子数组(子数组中的元素是连续的)。

题目名称:最小路径和
给定一个包含非负整数的m x n网格,请找出从左上角到右下角的路径,使得路径上的数字总和最小。

每次只能向下或向右移动一步。

题目名称:最长回文子串
给定一个字符串s,找到s中最长的回文子串。

你可以假设s的最大长度为1000。

题目名称:整数反转
给出一个32位的有符号整数,你需要将这个整数中每位上的数字进行反转。

注意:假设我们的环境只能存储得下32位的有符号整数,则其数值范围为[−2^31, 2^31 −1]。

请根据这个假设,如果反转后整数溢出那么就返回0。

题目名称:合并两个有序链表
将两个升序链表合并为一个新的升序链表并返回。

新链表是通过拼接给定的两个链表的所有节点组成的。

以上题目示例仅供参考,实际竞赛题目可能更加复杂和多样化。

参加Java ACM竞赛需要扎实的编程基础、算法和数据结构知识,以及良好的问题解决能力。

acm模板整理和使用方法

acm模板整理和使用方法

acm模板整理和使用方法[acm模板整理和使用方法]ACM模板指的是计算机科学中常用的算法模板,是计算机专业的学生在学习算法和数据结构时必需掌握的内容。

ACM模板整理和使用方法主要包括以下问题:一、为什么要使用ACM模板?ACM模板能使算法实现变得更简单、更方便、更快捷。

尤其在ACM竞赛中,使用优秀的模板可以节省编程时间,避免出现冗余代码,使得编程效率大幅提升。

二、哪些算法需要掌握?许多常见的算法,如快速排序、线段树、并查集、Kruskal算法、Dijkstra算法、最小生成树问题等,都需要掌握。

因此,算法学习和掌握是使用ACM模板的前提。

三、如何整理和使用ACM模板?1.整理ACM模板将常用的算法的代码整理,以函数或者类的形式存放在一个文件中。

注意代码要有良好的注释,易于阅读和理解。

2.旧的代码调试如果有其他ACM竞赛选手或者教练的旧代码,需要先将其调试通过。

因为在ACM比赛中,时间十分宝贵。

如果没有调试好的代码可以使用,建议可以使用OJ网站上的代码进行练习。

3.在比赛中使用和修改模板在ACM比赛中,选手需要快速编写正确的程序并提交到OJ网站。

使用模板可以节省时间和精力,但有时候需要针对具体的问题进行修改。

在修改时需要小心,一定要保证修改后的代码与原始模板的代码所实现的算法是等效的。

4.维护和更新模板ACM模板需要不断地维护和更新,特别是在涉及到新的算法或者数据结构时。

保证ACM模板的有效性和及时性非常重要,这需要持续的学习和探索。

四、如何学习和掌握ACM模板?1.选择学习和观察别人的代码一个好的方式是看国内和国际大佬们的代码,学习他们的代码风格和思考方式。

了解其他人的ACM模板如何实现,可以帮助你提高代码风格和技术水平。

2.探索自己不熟悉的算法和数据结构ACM竞赛中考察的算法不限于常见的算法,还包括各种数论、图论、动态规划等。

掌握这些算法和数据结构可以提高解题的速度和质量。

在掌握新算法之前,阅读相关论文或文章,掌握其基本原理和实现方法。

Java实训课程设计ACM题

Java实训课程设计ACM题

武汉科技大学城市学院课程设计报告课程设计名称Java课程设计题目ACM院系信息工程系专业班级姓名指导教师2019 年月日课程设计评分表任务书: Java & ACM在线评测1. 课程设计教学条件要求Eclipse2. 课程设计任务每个同学登录科技大学城市学院ACM10.10.4.55,点击作业,查看2019java课程设计,里面有13个测试题,要求在线完成8-12道题,每题写出解题报告,解题报告容:1.题目标题2.题目描述3.解题思路4.源码5.小结每个题目详细书写解题报告,一题多解的可以加分!!!3.课程设计参考资料[1]罗玉龙.java程序设计. :科学. 2012[2] 何玉洁. 数据库原理与应用教程. :机械工业.2003[3] 罗志高. 数据库原理与应用教程. :人民邮电.2003目录第1题小光棍数 (6)1.1题目描述 (6)1.2解题思路 (6)1.3解决方案 (7)1.4小结 (7)第2题寻找数列 (8)2.1题目描述 (8)2.2解题思路 (8)2.3解决方案 (9)2.4小结 (9)第3题奖学金 (10)3.1题目描述 (10)3.2解题思路 (11)3.3解决方案 (11)3.4小结 (12)第4题黄金分割数 (13)4.1题目描述 (13)4.2解题思路 (13)4.3解决方案 (14)4.4小结 (14)第5题星系炸弹--6TH 蓝桥杯C本科B组第二题 (15)5.1题目描述 (15)5.2解题思路 (15)5.3解决方案 (16)5.4小结 (16)第6题零起点学算法58---开灯问题 (17)6.1题目描述 (17)6.2解题思路 (17)6.3解决方案 (18)6.4小结 (18)第7题华科版C语言程序设计教程(第二版)习题5.7 (19)7.1题目描述 (19)7.2解题思路 (19)7.3解决方案 (20)7.4小结 (20)第8题整数划分1 (21)8.1题目描述 (21)8.2解题思路 (21)8.3解决方案 (22)8.4小结 (22)第1题小光棍数1.1题目描述为了迎接一年一度光棍节的到来,让我们一起来看看小光棍数吧。

ACM模板

ACM模板

字符串处理 (2)1、KMP算法 (2)2、扩展KMP (5)3、Manacher最长回文子串 (6)4、AC自动机 (7)5、后缀数组 (9)6、后缀自动机 (13)7、字符串HASH (15)数学 (17)1、素数 (17)2、素数筛选和合数分解 (19)3、扩展欧几里得算法(求ax+by=gcd的解以及逆元素) (20)4、求逆元 (20)5、模线性方程组 (20)6、随机素数测试和大数分解(POJ1811) (21)7、欧拉函数 (24)8、高斯消元(浮点数) (25)9、FFT (26)10、高斯消元法求方程组的解 (29)11、整数拆分 (34)12、求A^B的约数之和对MOD取模 (36)13、莫比乌斯反演 (37)14、Baby-StepGiant-Step (39)15、自适应simpson积分 (40)相关公式 (40)数据结构 (42)1、划分树 (42)2、RMQ (43)3、树链剖分 (45)4、伸展树(splaytree) (50)5、动态树 (55)6、主席树 (60)7、Treap (70)图论 (75)1、最短路 (75)2、最小生成树 (79)3、次小生成树 (80)4、有向图的强连通分量 (81)5、图的割点、桥和双连通分支的基本概念 (84)6、割点与桥 (85)7、边双连通分支 (88)8、点双连通分支 (90)9、最小树形图 (93)10、二分图匹配 (95)11、生成树计数 (98)11、二分图多重匹配 (101)12、KM算法(二分图最大权匹配) (102)13、最大流 (103)14、最小费用最大流 (109)15、2-SAT (110)16、曼哈顿最小生成树 (114)17、一般图匹配带花树 (117)18、LCA (120)19、欧拉路 (126)计算几何 (133)1、基本函数 (133)2、凸包 (138)3、平面最近点对(HDU1007) (139)4、旋转卡壳 (140)5、半平面交 (146)6、三点求圆心坐标(三角形外心) (149)7、求两圆相交的面积 (150)8、Pick公式 (150)动态规划 (150)1、最长上升子序列O(nlogn) (150)搜索 (151)1、DancingLinks (151)其他 (156)1、高精度 (156)2、完全高精度 (158)3、strtok 和sscanf结合输入 (163)4、解决爆栈,手动加栈 (163)5、STL (163)6、输入输出外挂 (165)7、莫队算法 (166)8、VIM配置 (172)字符串处理1、KMP 算法/** next[]的含义:x[i-next[i]...i-1]=x[0...next[i]-1]* next[i]为满足x[i-z...i-1]=x[0...z-1]的最大z值(就是x的自身匹配)*/void kmp_pre(char x[],int m,int next[]){int i,j;j=next[0]=-1;i=0;while(i<m){while(-1!=j && x[i]!=x[j])j=next[j];next[++i]=++j;}}/** kmpNext[]的意思:next'[i]=next[next[...[next[i]]]] (直到next'[i]<0或者x[next'[i]]!=x[i])* 这样的预处理可以快一些*/void preKMP(char x[],int m,int kmpNext[]){int i,j;j=kmpNext[0]=-1;i=0;while(i<m){while(-1!=j && x[i]!=x[j])j=kmpNext[j];if(x[++i]==x[++j])kmpNext[i]=kmpNext[j];else kmpNext[i]=j;}}/** 返回x在y中出现的次数,可以重叠*/int next[10010];int KMP_Count(char x[],int m,char y[],int n){//x是模式串,y是主串int i,j;int ans=0;//preKMP(x,m,next);kmp_pre(x,m,next);i=j=0;while(i<n){while(-1!=j && y[i]!=x[j])j=next[j];i++;j++;if(j>=m){ans++;j=next[j];}}return ans;}经典题目:POJ 3167/** POJ 3167 Cow Patterns* 模式串可以浮动的模式匹配问题* 给出模式串的相对大小,需要找出模式串匹配次数和位置* 比如说模式串:1,4,4,2,3,1 而主串:5,6,2,10,10,7,3,2,9 * 那么2,10,10,7,3,2就是匹配的** 统计比当前数小,和于当前数相等的,然后进行kmp*/#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <vector>usingnamespace std; constint MAXN=100010; constint MAXM=25010;int a[MAXN];int b[MAXN];int n,m,s;int as[MAXN][30];int bs[MAXM][30];void init(){for(int i=0;i<n;i++)word文档可自由复制编辑if(i==0){for(int j=1;j<=25;j++)as[i][j]=0;}else{for(int j=1;j<=25;j++)as[i][j]=as[i-1][j];}as[i][a[i]]++;}for(int i=0;i<m;i++){if(i==0){for(int j=1;j<=25;j++)bs[i][j]=0;}else{for(int j=1;j<=25;j++)bs[i][j]=bs[i-1][j];}bs[i][b[i]]++;}}int next[MAXM];void kmp_pre(){int i,j;j=next[0]=-1;i=0;while(i<m){int t11=0,t12=0,t21=0,t22=0;for(int k=1;k<b[i];k++){if(i-j>0)t11+=bs[i][k]-bs[i-j-1][k];else t11+=bs[i][k];}if(i-j>0)t12=bs[i][b[i]]-bs[i-j-1][b[i]];else t12=bs[i][b[i]];for(int k=1;k<b[j];k++){t21+=bs[j][k];}t22=bs[j][b[j]];if(j==-1 || (t11==t21&&t12==t22)){next[++i]=++j;}else j=next[j];}}vector<int>ans;void kmp(){ans.clear();int i,j;kmp_pre();i=j=0;while(i<n){int t11=0,t12=0,t21=0,t22=0;for(int k=1;k<a[i];k++){if(i-j>0)t11+=as[i][k]-as[i-j-1][k];else t11+=as[i][k];}if(i-j>0)t12=as[i][a[i]]-as[i-j-1][a[i]];else t12=as[i][a[i]];for(int k=1;k<b[j];k++){t21+=bs[j][k];}t22=bs[j][b[j]];if(j==-1 || (t11==t21&&t12==t22)){i++;j++;if(j>=m){ans.push_back(i-m+1);j=next[j];}}else j=next[j];}}int main(){while(scanf("%d%d%d",&n,&m,&s)==3){for(int i=0;i<n;i++){scanf("%d",&a[i]);}for(int i=0;i<m;i++){scanf("%d",&b[i]);}init();kmp();printf("%d\n",ans.size());for(int i=0;i<ans.size();i++)printf("%d\n",ans[i]);}return 0;}2、扩展KMP/** 扩展KMP算法*///next[i]:x[i...m-1]与x[0...m-1]的最长公共前缀//extend[i]:y[i...n-1]与x[0...m-1]的最长公共前缀void pre_EKMP(char x[],int m,int next[]){next[0]=m;int j=0;while(j+1<m && x[j]==x[j+1])j++;next[1]=j;int k=1;for(int i=2;i<m;i++){int p=next[k]+k-1;int L=next[i-k];if(i+L<p+1)next[i]=L;else{j=max(0,p-i+1);while(i+j<m && x[i+j]==x[j])j++;next[i]=j;k=i;}}}void EKMP(char x[],int m,char y[],int n,int next[],int extend[]) {pre_EKMP(x,m,next);int j=0;while(j<n && j<m && x[j]==y[j])j++;extend[0]=j;int k=0;for(int i=1;i<n;i++){int p=extend[k]+k-1;int L=next[i-k];if(i+L<p+1)extend[i]=L;else{j=max(0,p-i+1);while(i+j<n && j<m && y[i+j]==x[j])j++;extend[i]=j;k=i;}}}3、Manacher 最长回文子串/** 求最长回文子串*/const int MAXN=110010;char Ma[MAXN*2];int Mp[MAXN*2];void Manacher(char s[],int len){int l=0;Ma[l++]='$';Ma[l++]='#';for(int i=0;i<len;i++){Ma[l++]=s[i];Ma[l++]='#';}Ma[l]=0;int mx=0,id=0;for(int i=0;i<l;i++){Mp[i]=mx>i?min(Mp[2*id-i],mx-i):1;while(Ma[i+Mp[i]]==Ma[i-Mp[i]])Mp[i]++;if(i+Mp[i]>mx){mx=i+Mp[i];id=i;}}}/** abaaba*i: 0 1 2 3 4 5 6 7 8 9 10 11 1213* Ma[i]: $ # a # b # a # a $ b # a #* Mp[i]: 1 1 2 1 4 1 2 7 2 1 4 1 2 1*/char s[MAXN];int main(){while(scanf("%s",s)==1){int len=strlen(s);Manacher(s,len);int ans=0;for(int i=0;i<2*len+2;i++)ans=max(ans,Mp[i]-1);printf("%d\n",ans);}return 0;}4、AC 自动机//======================// HDU 2222// 求目标串中出现了几个模式串//====================#include <stdio.h>#include <algorithm>#include <iostream>#include <string.h>#include <queue>using namespace std;struct Trie{int next[500010][26],fail[500010],end[500010];int root,L;int newnode(){for(int i = 0;i < 26;i++)next[L][i] = -1;end[L++] = 0;return L-1;}void init(){L = 0;root = newnode();}void insert(char buf[]){int len = strlen(buf);int now = root;for(int i = 0;i < len;i++){if(next[now][buf[i]-'a'] == -1)next[now][buf[i]-'a'] = newnode();now = next[now][buf[i]-'a'];}end[now]++;}void build(){queue<int>Q;fail[root] = root;for(int i = 0;i < 26;i++)if(next[root][i] == -1)next[root][i] = root;else{fail[next[root][i]] = root;Q.push(next[root][i]);}while( !Q.empty() ){int now = Q.front();Q.pop();for(int i = 0;i < 26;i++)if(next[now][i] == -1)next[now][i] = next[fail[now]][i];else{fail[next[now][i]]=next[fail[now]][i];Q.push(next[now][i]);}}}int query(char buf[]){int len = strlen(buf);int now = root;int res = 0;for(int i = 0;i < len;i++){now = next[now][buf[i]-'a'];int temp = now;while( temp != root ){res += end[temp];end[temp] = 0;temp =fail[temp];}}return res;}void debug(){for(int i = 0;i <L;i++){printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);for(int j = 0;j < 26;j++)printf("%2d",next[i][j]);printf("]\n");}}};char buf[1000010];Trie ac;int main(){int T;int n;scanf("%d",&T);while( T-- ){scanf("%d",&n);ac.init();for(int i = 0;i <n;i++){scanf("%s",buf);ac.insert(buf);}ac.build();scanf("%s",buf);printf("%d\n",ac.query(buf));}return 0;}5、后缀数组5.1 DA 算法/**suffix array*倍增算法O(n*logn)*待排序数组长度为n,放在0~n-1中,在最后面补一个0*da(str,n+1,sa,rank,height,, );//注意是n+1;*例如:*n =8;*num[] = { 1, 1, 2, 1, 1, 1, 1, 2, $};注意num最后一位为0,其他大于0*rank[] = { 4, 6, 8, 1, 2, 3, 5, 7, 0 };rank[0~n-1]为有效值,rank[n]必定为0无效值*sa[] = { 8, 3, 4, 5, 0, 6, 1, 7, 2};sa[1~n]为有效值,sa[0]必定为n是无效值*height[]= { 0, 0, 3, 2, 3, 1, 2, 0, 1 };height[2~n]为有效值**/const int MAXN=20010;int t1[MAXN],t2[MAXN],c[MAXN];//求SA数组需要的中间变量,不需要赋值//待排序的字符串放在s数组中,从s[0]到s[n-1],长度为n,且最大值小于m,//除s[n-1]外的所有s[i]都大于0,r[n-1]=0//函数结束以后结果放在sa数组中bool cmp(int *r,int a,int b,int l){return r[a] == r[b] && r[a+l] == r[b+l];}void da(int str[],int sa[],int rank[],int height[],int n,int m){n++;int i, j, p, *x = t1, *y = t2;//第一轮基数排序,如果s的最大值很大,可改为快速排序for(i = 0;i < m;i++)c[i] = 0;for(i = 0;i < n;i++)c[x[i] = str[i]]++;for(i = 1;i < m;i++)c[i] += c[i-1];for(i = n-1;i >= 0;i--)sa[--c[x[i]]] = i;for(j = 1;j <= n; j <<= 1){p = 0;//直接利用sa数组排序第二关键字for(i = n-j; i < n; i++)y[p++] = i;//后面的j个数第二关键字为空的最小for(i = 0; i < n; i++)if(sa[i] >= j)y[p++] = sa[i] - j;//这样数组y保存的就是按照第二关键字排序的结果//基数排序第一关键字for(i = 0; i < m; i++)c[i] = 0;for(i = 0; i < n; i++)c[x[y[i]]]++;for(i = 1; i < m;i++)c[i] += c[i-1];for(i = n-1; i >= 0;i--)sa[--c[x[y[i]]]] = y[i];//根据sa和x数组计算新的x数组swap(x,y);p = 1; x[sa[0]] = 0;for(i = 1;i < n;i++)x[sa[i]] = cmp(y,sa[i-1],sa[i],j)?p-1:p++;if(p >= n)break;m = p;//下次基数排序的最大值}int k = 0;n--;for(i = 0;i <= n;i++)rank[sa[i]] = i;for(i = 0;i < n;i++){if(k)k--;j = sa[rank[i]-1];while(str[i+k] == str[j+k])k++;height[rank[i]] = k;}}int rank[MAXN],height[MAXN];int RMQ[MAXN];int mm[MAXN];int best[20][MAXN];void initRMQ(int n){mm[0]=-1;for(int i=1;i<=n;i++)mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];for(int i=1;i<=n;i++)best[0][i]=i;for(int i=1;i<=mm[n];i++)for(int j=1;j+(1<<i)-1<=n;j++){int a=best[i-1][j];int b=best[i-1][j+(1<<(i-1))];if(RMQ[a]<RMQ[b])best[i][j]=a;else best[i][j]=b;}}int askRMQ(int a,int b){int t;t=mm[b-a+1];b-=(1<<t)-1;a=best[t][a];b=best[t][b];return RMQ[a]<RMQ[b]?a:b;}int lcp(int a,int b){a=rank[a];b=rank[b];if(a>b)swap(a,b);return height[askRMQ(a+1,b)];}char str[MAXN];int r[MAXN];int sa[MAXN];int main(){while(scanf("%s",str) == 1){int len = strlen(str);int n = 2*len + 1;for(int i = 0;i < len;i++)r[i] = str[i];for(int i = 0;i < len;i++)r[len + 1 + i] = str[len - 1 - i];r[len] = 1;r[n] = 0;da(r,sa,rank,height,n,128);for(int i=1;i<=n;i++)RMQ[i]=height[i];initRMQ(n);int ans=0,st;int tmp;for(int i=0;i<len;i++){tmp=lcp(i,n-i);//偶对称if(2*tmp>ans){ans=2*tmp;st=i-tmp;}tmp=lcp(i,n-i-1);//奇数对称if(2*tmp-1>ans){ans=2*tmp-1;st=i-tmp+1;}}str[st+ans]=0;printf("%s\n",str+st);}return 0;}5.2 DC3 算法da[]和str[]数组要开大三倍,相关数组也是三倍/** 后缀数组* DC3算法,复杂度O(n)* 所有的相关数组都要开三倍*/const int MAXN = 2010;#define F(x) ((x)/3+((x)%3==1?0:tb))#define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)int wa[MAXN*3],wb[MAXN*3],wv[MAXN*3],wss[MAXN*3];int c0(int *r,int a,int b){return r[a] == r[b] && r[a+1] == r[b+1] && r[a+2] == r[b+2];}int c12(int k,int *r,int a,int b){if(k == 2)return r[a] < r[b] || ( r[a] == r[b] && c12(1,r,a+1,b+1) );else return r[a] < r[b] || ( r[a] == r[b] && wv[a+1] < wv[b+1] ); }void sort(int *r,int *a,int *b,int n,int m){int i;for(i = 0;i < n;i++)wv[i] = r[a[i]];for(i = 0;i < m;i++)wss[i] = 0;for(i = 0;i <n;i++)wss[wv[i]]++;for(i = 1;i < m;i++)wss[i] += wss[i-1];for(i = n-1;i >= 0;i--)b[--wss[wv[i]]] = a[i];}void dc3(int *r,int *sa,int n,int m){int i, j, *rn = r + n;int *san = sa + n, ta = 0, tb = (n+1)/3, tbc = 0, p;r[n] = r[n+1] = 0;for(i = 0;i < n;i++)if(i %3 != 0)wa[tbc++] = i;sort(r + 2, wa, wb, tbc, m);sort(r + 1, wb, wa, tbc, m);sort(r, wa, wb, tbc, m);for(p = 1, rn[F(wb[0])] = 0, i = 1;i < tbc;i++)rn[F(wb[i])] = c0(r, wb[i-1], wb[i]) ? p - 1 : p++;if(p < tbc)dc3(rn,san,tbc,p);else for(i = 0;i < tbc;i++)san[rn[i]] = i;for(i = 0;i < tbc;i++) if(san[i] < tb)wb[ta++] = san[i] * 3;if(n % 3 == 1)wb[ta++] = n - 1;sort(r, wb, wa, ta, m);for(i = 0;i < tbc;i++)wv[wb[i] = G(san[i])] = i;for(i = 0, j = 0, p = 0;i < ta && j < tbc;p++)sa[p] = c12(wb[j] % 3, r, wa[i], wb[j]) ? wa[i++] : wb[j++];for(;i < ta;p++)sa[p] = wa[i++];for(;j < tbc;p++)sa[p] = wb[j++];}//str和sa也要三倍void da(int str[],int sa[],int rank[],int height[],int n,int m){for(int i = n;i < n*3;i++)str[i] = 0;dc3(str, sa, n+1, m);int i,j,k = 0;for(i = 0;i <= n;i++)rank[sa[i]] = i;for(i = 0;i < n; i++){if(k) k--;j = sa[rank[i]-1]; while(str[i+k]== str[j+k]) k++; height[rank[i]]=k;}}6、后缀自动机const int CHAR = 26;const int MAXN = 250010;struct SAM_Node{SAM_Node *fa,*next[CHAR];int len;int id,pos;SAM_Node(){}SAM_Node(int _len){fa = 0;len = _len;memset(next,0,sizeof(next));}};SAM_Node SAM_node[MAXN*2], *SAM_root, *SAM_last;int SAM_size;SAM_Node *newSAM_Node(int len){SAM_node[SAM_size] = SAM_Node(len);SAM_node[SAM_size].id = SAM_size;return &SAM_node[SAM_size++];}SAM_Node *newSAM_Node(SAM_Node *p){SAM_node[SAM_size] = *p;SAM_node[SAM_size].id = SAM_size;return &SAM_node[SAM_size++];}void SAM_init(){SAM_size = 0;SAM_root = SAM_last = newSAM_Node(0);SAM_node[0].pos = 0;}void SAM_add(int x,int len){SAM_Node *p = SAM_last, *np = newSAM_Node(p->len+1);np->pos = len;SAM_last = np;for(;p && !p->next[x];p = p->fa)p->next[x] = np;if(!p){np->fa = SAM_root;return;}SAM_Node *q = p->next[x];if(q->len == p->len + 1){np->fa = q;return;}SAM_Node *nq = newSAM_Node(q);nq->len = p->len + 1;q->fa = nq;np->fa = nq;for(;p && p->next[x] == q;p = p->fa)p->next[x] = nq;}void SAM_build(char *s){SAM_init();int len = strlen(s);for(int i = 0;i < len;i++)SAM_add(s[i] - 'a',i+1);}//加入串后进行拓扑排序。

赛马网ACM试题(原杭电ojACM)java版答案(1000,10001,1002)

赛马网ACM试题(原杭电ojACM)java版答案(1000,10001,1002)

赛马⽹ACM试题(原杭电ojACM)java版答案(1000,10001,1002)赛马⽹ACM试题(原杭电OJ ACM试题)答案(java版)突然⼿痒,来做⼀下acm试题练练⼿,由于最近在学java,顺便练⼀下java编程。

但是对于ACM训练,c会更好,因为c的时间效率更⾼⼀些,这⽅⾯⽐java有优势。

其实调调⼩程序就像品茶⼀样也挺有意思的(怎么闻到⼀股屌丝⽓息)。

最近也在找⼯作阶段,对于新兴的在线⽐赛,在线程序测试略有感触,这是⼀个⼤趋势,也是互联⽹公司招聘的⼀个优势吧,不过诸多问题还有待改善,这⾥不详述。

对于计算机专业出⾝,编程是基础,想要进阶,就先积累点滴吧。

注意:提交的java代码的类名都必须为Main第1000题:A+B ProblemProblem DescriptionCalculateA + B.InputEach line will contain two integersA andB. Process to end of file.OutputFor each case, outputA +B in one line.Sample Input1 1Sample Output2题⽬解析:要求每⾏输⼊两个数,计算两数的和并输出,这⾥是要循环的输⼊,程序⾃动输出!代码:import java.util.Scanner;public class Main{public static void main(String[] args){Scanner in = new Scanner(System.in);while(in.hasNextInt()){int a = in.nextInt();int b = in.nextInt();System.out.println(a+b);}}}第1001题:Sum ProblemProblem DescriptionHey, welcome to HDOJ(Hangzhou Dianzi University Online Judge).In this problem, your task is to calculate SUM(n) = 1 + 2 + 3 + ... + n.InputThe input will consist of a series of integers n, one integer per line.OutputFor each case, output SUM(n) in one line, followed by a blank line. You may assume the result will be in the range of 32-bit signed integer. Sample Input1100Sample Output15050题⽬解析:输⼊⼀个数n,计算1+2+3+...+n的值。

ACM中使用java

ACM中使用java

ACM中使用java目录java输出重定向 (2)java输入重定向 (2)java中使用控制台输入 (2)java输入输出重定向 (3)Java中输入多组数据时的技巧 (3)Java中对象无重复排序 (4)单链表 (7)循环链表 (9)栈 (11)队列 (13)二叉排序树 (15)最小生成树(普里姆算法) (18)深度优先搜索和广度优先搜索 (21)最短路径求解—Dijkstra算法 (26)1、java输出重定向import java.io.FileOutputStream;import java.io.PrintStream;public class Main {public static void main(String args[]) throws Exception { PrintStream out = new PrintStream(newFileOutputStream("pc2.estdout"));System.setOut(out);System.out.println("Hello World!");out.close();}}2、java输入重定向import java.io.BufferedInputStream;import java.io.FileInputStream;import java.util.Scanner;public class Test08 {public static void main(String[] args) throws Exception { // 输入重定向BufferedInputStream in = new BufferedInputStream(new FileInputStream("std.in"));System.setIn(in);Scanner stdin = new Scanner(System.in);int a = stdin.nextInt();int b = stdin.nextInt();System.out.print(a + b);}}3、java中使用控制台输入import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner input = new Scanner(System.in);String str1 = input.nextLine();System.out.println(str1);}}4、java输入输出重定向import java.io.BufferedInputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.PrintStream;import java.util.Scanner;public class Main {public static void main(String[] args) throws Exception { // 输入重定向BufferedInputStream in = new BufferedInputStream(new FileInputStream("std.in"));System.setIn(in);Scanner stdin = new Scanner(System.in);int a = stdin.nextInt();int b = stdin.nextInt();// 输出重定向PrintStream out = new PrintStream(new FileOutputStream("estdout.pc2"));System.setOut(out);System.out.print(a + b);out.close(); // 关闭重定向}}Java中输入多组数据时的技巧public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int m = sc.nextInt(); // 表示有m组数据Activity[] act = null;Activity[][] t = new Activity[m][];for (int i = 0; i < m; i++) {int n = sc.nextInt(); // 表示有n个活动act = new Activity[n];for (int k = 0; k < n; k++) {act[k] = new Activity();}for (int j = 0; j < n; j++) {act[j].setTime(sc.nextInt(), sc.nextInt());}t[i] = act;}for (int i = 0; i < m; i++) {sort(t[i]);delete(t[i]);System.out.println(count(t[i]));}}Java中对象无重复排序import java.util.ArrayList;import java.util.Arrays;import /doc/845677777.html,parator; import java.util.HashSet;import java.util.Scanner;public class Per {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int m = sc.nextInt(); // 代表m组测试数据for (int i = 0; i < m; i++) {int n = sc.nextInt(); // 代表n个长方形Rect[] s = new Rect[n];for (int j = 0; j < n; j++) {int a = sc.nextInt();int b = sc.nextInt();int c = sc.nextInt();int height = b > c ? b : c;int width = b < c ? b : c;s[j] = new Rect(a, height, width);}HashSet set = new HashSet();ArrayList list = new ArrayList();for (int j = 0; j < s.length; j++) {if (set.add(s[j]))list.add(s[j]);}Object[] arr = list.toArray();Arrays.sort(arr, new MyComparator());for (Object j : arr)System.out.println(j);}}public static class MyComparator implements Comparator { @Overridepublic int compare(Object o1, Object o2) {Rect rc1 = (Rect) o1;Rect rc2 = (Rect) o2;if (rc1.id > rc2.id) {return 1;} else if (rc1.id < rc2.id) {return -1;} else {if (rc1.height > rc2.height) {return 1;} else if (rc1.height < rc2.height) {return -1;} else {if (rc1.width > rc2.width) {return 1;} else if (rc1.width < rc2.width) {return -1;} elsereturn 0;}}}}public static class Rect {int height;int id;int width;public Rect(int i, int hei, int wid) {height = hei;id = i;width = wid;}public String toString() {return id + " " + height + " " + width;}public boolean equals(Object o) {Rect t = (Rect) o;return t.height == height && t.id == id && t.width == width; }public int hashCode() {return 3 * height + 4 * id + 5 * width;}}}Java中的常用数据结构1.单链表public class Main {public static void main(String[] args){LinkList l = new LinkList();l.add("A");l.add("B");l.add("C");l.add("D");l.add("E");printList(l.head);System.out.println();LinkNode t = l.search("E");System.out.println(t.data);l.delete("E");LinkNode t1 = l.search("E");System.out.println(t1.data);}public static void printList(LinkNode tmp){System.out.print(tmp.data+" ");if(tmp.next!=null){printList(tmp.next);}}}//定义节点类class LinkNode{Object data = null; //保存节点内容LinkNode next = null; //保存节点的下一个节点public LinkNode(Object data){this(data,null);}public LinkNode(Object data,LinkNode tmp){ this.data = data;this.next = tmp;}}//定义链表类,对节点进行封装class LinkList{LinkNode head = null; //定义头结点LinkNode p = null; //p节点用来保存节点移动后的当前位置//向链表中增加成员public void add(Object data){LinkNode tmp = new LinkNode(data);if(head==null){head = tmp;p = tmp;p.next = null;}else{p.next = tmp;p = tmp;p.next = null;}}//查找链表中的某节点public LinkNode search(Object data){p = head;boolean i = false; //用于判断节点是否找到while(p!=null){if(p.data==data){i = true;break;}p = p.next;}if(i==false){return (new LinkNode("不存在"));}else{return p;}}//删除链表中某节点public void delete(Object data){if(search(data).data=="不存在"){System.out.println("找不到该节点,删除失败!");}else{LinkNode tmp;tmp = search(data); //找到要删除的节点tmpif(tmp.next!=null){LinkNode ch; //通过将要删除的节点(即tmp)的下一个节点的内容传给tmp,ch = tmp.next; //然后再将tmp的下一个节点从链表中移走达到删除tmp的目的tmp.data = ch.data;tmp.next = ch.next;}else{ //如果要删除的是最后一个结点,则将节点的内容修改,search(data).data = "不存在"; //相当于删除了该节点}}}}2.循环链表public class Main {public static void main(String[] args){ LinkList l = new LinkList();l.setLen(30);l.createLink();l.setK(1);l.setM(9);l.play();}}class Node{int data;Node next;public Node(int data){this.data = data;}}class LinkList{Node head = null; //定义头节点Node p = null; //定义p保存当前节点的位置int len = 0; //保存链表的长度int k = 0; //保存从第几人开始报数int m = 0; //保存报到第几个数public void setLen(int len){this.len = len; //设置链表长度}public void setK(int k){this.k = k; //设置从第几人开始报数}public void setM(int m){this.m = m; //设置报到第几个数}public void createLink(){for(int i=1;i<=len;i++){Node ch = new Node(i); //生成一个新节点if(i==1){head = ch; //将第一个新节点设为头节点p = ch; //p保存移动后的当前位置的节点}else if(i==len){p.next = ch;p = ch;p.next= head; //将最后一个节点的下一个节点设为头节点,形成循环链表}else{p.next = ch;p = ch;}}}public void show(Node node){System.out.print(node.data+" ");}public void play(){char[] a = new char[30];for(int i=0;i<a.length;i++){< p="">a[i] = '@';}p = head;//找到第k个人for(int i=1;i<k;i++){< p="">p = p.next;}while(this.len!=15){for(int i=1;i<m;i++){< p="">p = p.next;}//show(p); //打印读到m的人a[p.data-1] = '+';//删除第m个人Node tmp = p.next;p.data = tmp.data;p.next = tmp.next;this.len--;};for(int i=0;i<a.length;i++){< p=""> System.out.print(a[i]);}}}3.栈public class Main {public static void main(String[] args){ StackLi sl = new StackLi();sl.push("A");sl.push("B");sl.push("C");sl.push("D");sl.push("E");print(sl.getTopStack()); //从栈顶开始向下输出元素sl.pop();sl.pop();sl.pop();sl.pop();print(sl.getTopStack());print(sl.getTopStack()); //输出栈顶元素}public static void print(ListNode node){if(node==null){System.out.println("桟是空的,没有元素可以输出!"); }else{ System.out.print(node.element+" ");if(node.next!=null){print(node.next);}else{System.out.println(); //桟中全部元素输出后换行 }}}}//定义异常类class Underflow extends Throwable{private String info;public Underflow(){System.out.println("桟已空,无法出桟!");}}//定义链表节点类class ListNode{Object element;ListNode next;public ListNode(Object c){this(c,null);}public ListNode(Object c,ListNode node){ this.element = c;this.next = node;}}//定义桟类class StackLi{private ListNode topOffStack;public StackLi(){topOffStack = null;}//取得栈顶public ListNode getTopStack(){return topOffStack;}//判断是否桟满public boolean isFull(){return false;}//判断是否桟空public boolean isEmpty(){return topOffStack == null;}//清空桟public void makeEmpty(){ topOffStack = null;}//进栈public void push(Object x){topOffStack = new ListNode(x,topOffStack); } //出桟public void pop(){if (isEmpty()){new Underflow();}else{topOffStack = topOffStack.next;}}//出桟并取得栈顶内容public Object topAndPop(){if(isEmpty()){return null;}Object topItem = topOffStack.element; topOffStack = topOffStack.next;return topItem;}}4.队列public class Main {public static void main(String[] args){ QueueAr qa = new QueueAr();qa.enqueue("A"); //依次入队qa.enqueue("B");qa.enqueue("C");qa.enqueue("D");qa.enqueue("E");qa.dequeue(); //出队print(qa.getFront()); //打印队列中所有成员qa.enqueue("F");print(qa.getFront());qa.makeEmpty(); //清空队列print(qa.getFront());}public static void print(ListNode node){if(node==null){System.out.println("队列是空的,没有元素可以输出!"); }else{ System.out.print(node.element+" ");if(node.next!=null){print(node.next);}else{System.out.println(); //队列中全部元素输出后换行 }}}}//定义链表节点类class ListNode{Object element;ListNode next;public ListNode(Object c){this(c,null);}public ListNode(Object c,ListNode node){ this.element = c; this.next = node;}}//定义队列class QueueAr{private ListNode front;private ListNode back;public QueueAr(){back = null;front = null;}//判断队列是否为空public boolean isEmpty(){return front == null;}//判断队列是否满,此处队列永远不会满public boolean isFull(){return false;}//清空队列public void makeEmpty(){front = null;back = null;}//去的队列头public ListNode getFront(){return front;}//入队public void enqueue(Object x){ ListNode ch = new ListNode(x);if(isEmpty()){back = ch;front = back;}else{back.next = ch;back = ch;}}//出队public void dequeue(){if(isEmpty()==true){System.out.println("队列已空,无法出队!");}else{front = front.next;}}}5.二叉排序树public class TreeDemo02 {public static void main(String[] args) { BinarySearchTree btr = new BinarySearchTree(); btr.insert(6);btr.insert(2);btr.insert(1);btr.insert(3);btr.insert(4);btr.insert(8);System.out.println(btr.find(4));System.out.println(btr.findMin());System.out.println(btr.findMax());btr.printTree();}}// 定义树节点class BinaryNode {Comparable element; // 保存节点内容BinaryNode left; // 保存节点的左孩子BinaryNode right; // 保存节点的右孩子// 定义构造函数,初始化成员BinaryNode(Comparable theElement) {this(theElement, null, null);}BinaryNode(Comparable theElement, BinaryNode lt, BinaryNode rt) { element = theElement;left = lt;right = rt;}}// 定义二叉查找树,将树节点封装成树并进行各种操作class BinarySearchTree {private BinaryNode root;public BinarySearchTree() {root = null;}// 判断树是否为空public boolean isEmpty() {return root == null;}// 查找树中是否存在某节点public Comparable find(Comparable x) { return find2(x, root).element;}// 查找树中最小的节点public Comparable findMin() {return findMin2(root).element;}// 查找树中最大的节点public Comparable findMax() {return findMax2(root).element;}// 向树中插入某节点public void insert(Comparable x) {root = insert2(x, root);}// 删除树中某节点public void remove(Comparable x) {root = remove2(x, root);}// 遍历二叉树public void printTree() {if (isEmpty()) {System.out.println("Empty Tree!");} else {printTree2(root);System.out.println();}}// 查找的具体操作,该操作对外是透明的,后面的操作同理private BinaryNode find2(Comparable x, BinaryNode t) {// 如果不存在,就新添加一个辅助树节点,并将其内容设为不存在if (t == null) {BinaryNode s = new BinaryNode("不存在该元素!");return s;}if(/doc/845677777.html,pareTo(t.element)< 0) { // 如果查找的元素比当前根节点小,则继续再该节点的左子树中查找,直至根节点为空return find2(x, t.left);} else if (/doc/845677777.html,pareTo(t.element) > 0) { // 如果查找的元素比当前根节点大,则继续再该节点的右子树中查找,直至根节点为空return find2(x, t.right);} elsereturn t; // 如果查找的节点内容和当前根节点的内容相等,则返回当前根节点}// 找最小节点的具体过程private BinaryNode findMin2(BinaryNode t) {if (t == null) {return null;} else if (t.left == null) {return t;}return findMin2(t.left);}// 找最大节点的具体过程private BinaryNode findMax2(BinaryNode t) {if (t != null) {while (t.right != null) {t = t.right;}}return t;}// 构造二叉查找树的具体过程private BinaryNode insert2(Comparable x, BinaryNode t) {if (t == null) { // 若树是空的,则构造一棵新的树,t为树的根t = new BinaryNode(x, null, null);} else if (/doc/845677777.html,pareTo(t.element)< 0) { // 如果要插入的元素小于当前节点,则插入在该节点的左边t.left = insert2(x, t.left);} else if (/doc/845677777.html,pareTo(t.element) > 0) { // 如果要插入的元素大于当前节点,则插入在该节点的又边t.right = insert2(x, t.right);} else; // 否则什么也不做return t;}// 删除节点的具体操作过程private BinaryNode remove2(Comparable x, BinaryNode t) { if (t == null) {return t;}if(/doc/845677777.html,pareTo(t.element)< 0) {t.left = remove2(x, t.left);} else if(/doc/845677777.html,pareTo(t.element) > 0) {t.right = remove2(x, t.right);} else if (t.left != null && t.right != null) {t.element = findMin2(t.right).element;t.right = remove2(x, t.right);} else {t = (t.left != null) ? t.left : t.right;}return t;}// 遍历二叉树的具体过程private void printTree2(BinaryNode t) {if (t != null) {printTree2(t.left);System.out.print(t.element + " ");printTree2(t.right);}}}6、最小生成树(普里姆算法)import java.util.Scanner;public class PrimDemo {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNext()) {int n = sc.nextInt();// 图的顶点数int m = sc.nextInt(); // 图的边数if (n == 0 && m == 0)break;int[][] map = new int[n][n]; //存放边的权值for (int i = 0; i < n; ++i) {for (int j = 0; j < n; ++j) {map[i][j] = Integer.MAX_VALUE; //起点i,终点为j的边的权植。

核心算法——ACM模板

核心算法——ACM模板

核心算法——ACM模板一、贪心算法 (2)1、区间选点 (2)2、区间覆盖 (2)3、不相交区间 (2)4、哈夫曼编码 (2)5、最小值最大化、最大值最小化(二分查找) (2)二、动态规划 (5)1、最长公共子序列(LCS) (5)2、最长上升公共子序列(LIS) (7)3、子段和 (9)4、DAG上的动态规划 (13)5、区间DP (17)6、状态压缩DP (24)7、双线DP (30)8、背包问题(见背包九讲) (32)三、数据结构 (32)1、并查集 (32)2、树状数组 (34)3、(字符串)KMP匹配 (37)四、最小生成树算法 (41)Prime核心算法 (41)Kruskal算法 (44)五、单源最短路径 (50)Dijkstra核心算法 (50)Bellman_Ford算法 (54)SPFA算法(Bellman_Ford的队列实现) (58)六、二分图匹配 (61)1、匈牙利算法 (61)七、网络流 (63)1、SAP算法 (64)2、Dinic算法 (68)一、贪心算法1、区间问题区间选点选取尽量少的点覆盖所有的区间,是每个区间至少包含一个点。

对区间右端点进行排序。

区间覆盖选取尽量少的区间覆盖整个区域。

对左端点进行排序。

不相交区间选取尽量多的不相交区间。

对区间右端点进行排序。

2、哈夫曼编码3、最小值最大化、最大值最小化(二分查找)NYOJ 疯牛问题(最小值最大化)农夫John 建造了一座很长的畜栏,它包括N (2 <= N <= 100,000)个隔间,这些小隔间依次编号为x1,...,xN (0 <= xi <= 1,000,000,000).但是,John的C (2 <= C <= N)头牛们并不喜欢这种布局,而且几头牛放在一个隔间里,他们就要发生争斗。

为了不让牛互相伤害。

John决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是什么呢?#include#include#includeusing namespace std;int n, c;int pos[100005];bool judge(int k){int cnt = 1;int st = pos[0];for(int i = 1; i < n; ++i){if(pos[i] - st >= k){++cnt;if(cnt >= c)return true;st = pos[i];}}return false;}int Binary_search(int left, int right) /// 二分枚举满足条件的最大距离{while(left <= right){int mid = (left + right) >> 1;if(judge(mid)) /// 所求距离 >= mid,可以继续增大试探left = mid+1;else /// 所求距离 < mid,所以必须减小来试探right = mid-1;}return left-1;}int main(){while(~scanf("%d%d", &n, &c)){for(int i = 0; i < n; ++i)scanf("%d", &pos[i]);sort(pos, pos+n);printf("%d\n", Binary_search(0, pos[n-1] - pos[0]));}return 0;}NYOJ 摘枇杷(最大值最小化)理工学院的枇杷快熟了,ok,大家都懂得。

-【精品资料】ACM大赛必备_常用函数整理_ACM模板(整理版)

-【精品资料】ACM大赛必备_常用函数整理_ACM模板(整理版)

目录一、数学问题 (4)1.精度计算——大数阶乘 (4)2.精度计算——乘法(大数乘小数) (4)3.精度计算——乘法(大数乘大数) (5)4.精度计算——加法 (6)5.精度计算——减法 (7)6.任意进制转换 (8)7.最大公约数、最小公倍数 (9)8.组合序列 (10)9.快速傅立叶变换(FFT) (10)10.Ronberg 算法计算积分 (12)11.行列式计算 (14)12.求排列组合数 (15)13.求某一天星期几 (15)14.卡特兰(Catalan) 数列原理 (16)15.杨辉三角 (16)16.全排列 (17)17.匈牙利算法----最大匹配问题 (18)18.最佳匹配KM 算法 (20)二、字符串处理 (22)1.字符串替换 (22)2.字符串查找 (23)3.字符串截取 (24)4.LCS-最大公共子串长度 (24)5.LCS-最大公共子串长度 (25)6.数字转换为字符 (26)三、计算几何 (27)1.叉乘法求任意多边形面积 (27)2.求三角形面积 (27)3.两矢量间角度 (28)4.两点距离(2D、3D) (28)5.射向法判断点是否在多边形内部 (29)6.判断点是否在线段上 (30)7.判断两线段是否相交 (31)8.判断线段与直线是否相交 (32)9.点到线段最短距离 (32)10.求两直线的交点 (33)11.判断一个封闭图形是凹集还是凸集 (34)12.Graham 扫描法寻找凸包 (35)13.求两条线段的交点 (36)四、数论 (37)1.x 的二进制长度 (37)2.返回x 的二进制表示中从低到高的第i 位 (38)3.模取幂运算 (38)4.求解模线性方程 (39)5.求解模线性方程组(中国余数定理) (39)6.筛法素数产生器 (40)7.判断一个数是否素数 (41)8.求距阵最大和 (42)8.求一个数每一位相加之和 (43)10.质因数分解 (43)11.高斯消元法解线性方程组 (44)五、图论 (45)1.Prim 算法求最小生成树................................................. 45 2.Dijkstra 算法求单源最短路径.. (46)3.Bellman-ford 算法求单源最短路径 (47)4.Floyd-Warshall 算法求每对节点间最短路径 (48)5.解欧拉图 (49)六、排序/查找 (50)1.快速排序 (50)2.希尔排序 (51)3.选择法排序 (52)4.二分查找 (52)七、数据结构 (53)1.顺序队列 (53)2.顺序栈 (56)3.链表 (59)4.链栈 (63)5.二叉树 (66)八、高精度运算专题 (68)1.专题函数说明 (68)2.高精度数比较 (69)3.高精度数加法 (69)4.高精度数减法 (70)5.高精度乘10 (71)6.高精度乘单精度 (71)7.高精度乘高精度 (72)8.高精度除单精度 (72)9.高精度除高精度 (73)九、标准模板库的使用 (74)1.计算求和 (74)2.求数组中的最大值 (76)3. sort 和qsort (76)十、其他 (78)1.运行时间计算 (78)DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD一、数学问题1.精度计算——大数阶乘语法:int result=factorial(int n);参数:n:n 的阶乘返回值:阶乘结果的位数注意:本程序直接输出n!的结果,需要返回结果请保留long a[] 需要math.h源程序:int factorial(int n){long a[10000];int i,j,l,c,m=0,w;a[0]=1;for(i=1;i<=n;i++){c=0;for(j=0;j<=m;j++){a[j]=a[j]*i+c;c=a[j]/10000;a[j]=a[j]%10000;}if(c>0) {m++;a[m]=c;}}w=m*4+log10(a[m])+1;printf("\n%ld",a[m]);for(i=m-1;i>=0;i--) printf("%4.4ld",a[i]);return w;}我也可以做到..5 / 782.精度计算——乘法(大数乘小数)语法:mult(char c[],char t[],int m);参数:c[]:被乘数,用字符串表示,位数不限t[]:结果,用字符串表示m:乘数,限定10 以内返回值:null注意:需要string.h源程序:void mult(char c[],char t[],int m){int i,l,k,flag,add=0;char s[100];l=strlen(c);for (i=0;i<l;i++)s[l-i-1]=c[i]-'0';for (i=0;i<l;i++){k=s[i]*m+add;if (k>=10) {s[i]=k%10;add=k/10;flag=1;} else{s[i]=k;flag=0;add=0;}}if (flag) {l=i+1;s[i]=add;} else l=i;for (i=0;i<l;i++)t[l-1-i]=s[i]+'0'; t[l]='\0';}3.精度计算——乘法(大数乘大数)语法:mult(char a[],char b[],char s[]);参数:a[]:被乘数,用字符串表示,位数不限b[]:乘数,用字符串表示,位数不限t[]:结果,用字符串表示返回值:null注意:空间复杂度为o(n^2)需要string.h源程序:void mult(char a[],char b[],char s[]){我也可以做到..6 / 78int i,j,k=0,alen,blen,sum=0,res[65][65]={0},flag=0; char result[65];alen=strlen(a);blen=strlen(b);for (i=0;i<alen;i++)for (j=0;j<blen;j++) res[i][j]=(a[i]-'0')*(b[j]-'0');for (i=alen-1;i>=0;i--){for (j=blen-1;j>=0;j--) sum=sum+res[i+blen-j-1][j]; result[k]=sum%10;k=k+1;sum=sum/10;}for (i=blen-2;i>=0;i--){for (j=0;j<=i;j++) sum=sum+res[i-j][j];result[k]=sum%10;k=k+1;sum=sum/10;}if (sum!=0) {result[k]=sum;k=k+1;}for (i=0;i<k;i++) result[i]+='0';for (i=k-1;i>=0;i--) s[i]=result[k-1-i];s[k]='\0';while(1){if (strlen(s)!=strlen(a)&&s[0]=='0')strcpy(s,s+1);elsebreak;}}4.精度计算——加法语法:add(char a[],char b[],char s[]);参数:a[]:被加数,用字符串表示,位数不限b[]:加数,用字符串表示,位数不限s[]:结果,用字符串表示返回值:null注意:空间复杂度为o(n^2)我也可以做到..7 / 78需要string.hDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD源程序:void add(char a[],char b[],char back[]){int i,j,k,up,x,y,z,l;char *c;if (strlen(a)>strlen(b)) l=strlen(a)+2; else l=strlen(b)+2; c=(char *) malloc(l*sizeof(char));i=strlen(a)-1;j=strlen(b)-1;k=0;up=0;while(i>=0||j>=0){if(i<0) x='0'; else x=a[i];if(j<0) y='0'; else y=b[j];z=x-'0'+y-'0';if(up) z+=1;if(z>9) {up=1;z%=10;} else up=0;c[k++]=z+'0';i--;j--;}if(up) c[k++]='1';i=0;c[k]='\0';for(k-=1;k>=0;k--)back[i++]=c[k];back[i]='\0';}5.精度计算——减法语法:sub(char s1[],char s2[],char t[]);参数:s1[]:被减数,用字符串表示,位数不限s2[]:减数,用字符串表示,位数不限t[]:结果,用字符串表示返回值:null注意:默认s1>=s2,程序未处理负数情况需要string.h源程序:void sub(char s1[],char s2[],char t[])我也可以做到..8 / 78{int i,l2,l1,k;l2=strlen(s2);l1=strlen(s1);t[l1]='\0';l1--;for (i=l2-1;i>=0;i--,l1--){if (s1[l1]-s2[i]>=0)t[l1]=s1[l1]-s2[i]+'0';else{t[l1]=10+s1[l1]-s2[i]+'0';s1[l1-1]=s1[l1-1]-1;}}k=l1;while(s1[k]<0) {s1[k]+=10;s1[k-1]-=1;k--;}while(l1>=0) {t[l1]=s1[l1];l1--;}loop:if (t[0]=='0') {l1=strlen(s1);for (i=0;i<l1-1;i++) t[i]=t[i+1];t[l1-1]='\0';goto loop;}if (strlen(t)==0) {t[0]='0';t[1]='\0';}}6.任意进制转换语法:conversion(char s1[],char s2[],char t[]);参数:s[]:转换前的数字s2[]:转换后的数字d1:原进制数d2:需要转换到的进制数返回值:null注意:高于9 的位数用大写'A'~'Z'表示,2~16 位进制通过验证源程序:void conversion(char s[],char s2[],long d1,long d2){我也可以做到..9 / 78long i,j,t,num;char c;num=0;for (i=0;s[i]!='\0';i++){if (s[i]<='9'&&s[i]>='0') t=s[i]-'0'; else t=s[i]-'A'+10;num=num*d1+t;}i=0;while(1){t=num%d2;if (t<=9) s2[i]=t+'0'; else s2[i]=t+'A'-10;num/=d2;if (num==0) break;i++;}for (j=0;j<i/2;j++){c=s2[j];s2[j]=s[i-j];s2[i-j]=c;}s2[i+1]='\0';}7.最大公约数、最小公倍数语法:resulet=hcf(int a,int b)、result=lcd(int a,int b)参数:a:int a,求最大公约数或最小公倍数b:int b,求最大公约数或最小公倍数返回值:返回最大公约数(hcf)或最小公倍数(lcd)注意:lcd 需要连同hcf 使用源程序:int hcf(int a,int b){int r=0;while(b!=0){r=a%b;a=b;DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDb=r;}return(a);我也可以做到..10 / 78}lcd(int u,int v,int h){return(u*v/h);}8.组合序列语法:m_of_n(int m, int n1, int m1, int* a, int head)参数:m:组合数C 的上参数n1:组合数C 的下参数m1:组合数C 的上参数,递归之用*a:1~n 的整数序列数组head:头指针返回值:null注意:*a 需要自行产生初始调用时,m=m1、head=0调用例子:求C(m,n)序列:m_of_n(m,n,m,a,0);源程序:void m_of_n(int m, int n1, int m1, int* a, int head){int i,t;if(m1<0 || m1>n1) return;if(m1==n1){return;}m_of_n(m,n1-1,m1,a,head); // 递归调用t=a[head];a[head]=a[n1-1+head];a[n1-1+head]=t;m_of_n(m,n1-1,m1-1,a,head+1); // 再次递归调用t=a[head];a[head]=a[n1-1+head];a[n1-1+head]=t;}9.快速傅立叶变换(FFT)语法:kkfft(double pr[],double pi[],int n,int k,double fr[],double fi[],intl,int il);参数:我也可以做到..11 / 78pr[n]:输入的实部pi[n]:数入的虚部n,k:满足n=2^kfr[n]:输出的实部fi[n]:输出的虚部l:逻辑开关,0 FFT,1 ifFTil:逻辑开关,0 输出按实部/虚部;1 输出按模/幅角返回值:null注意:需要math.h源程序:void kkfft(pr,pi,n,k,fr,fi,l,il)int n,k,l,il;double pr[],pi[],fr[],fi[];{int it,m,is,i,j,nv,l0; double p,q,s,vr,vi,poddr,poddi;for (it=0; it<=n-1; it++){m=it; is=0;for (i=0; i<=k-1; i++){j=m/2; is=2*is+(m-2*j); m=j;}fr[it]=pr[is]; fi[it]=pi[is];}pr[0]=1.0; pi[0]=0.0;p=6.283185306/(1.0*n);pr[1]=cos(p); pi[1]=-sin(p);if (l!=0) pi[1]=-pi[1];for (i=2; i<=n-1; i++){p=pr[i-1]*pr[1];q=pi[i-1]*pi[1];s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]);pr[i]=p-q; pi[i]=s-p-q;}for (it=0; it<=n-2; it=it+2){vr=fr[it]; vi=fi[it];fr[it]=vr+fr[it+1]; fi[it]=vi+fi[it+1];fr[it+1]=vr-fr[it+1]; fi[it+1]=vi-fi[it+1]; }m=n/2; nv=2;for (l0=k-2; l0>=0; l0--){我也可以做到..12 / 78m=m/2; nv=2*nv;for (it=0; it<=(m-1)*nv; it=it+nv)for (j=0; j<=(nv/2)-1; j++){p=pr[m*j]*fr[it+j+nv/2];q=pi[m*j]*fi[it+j+nv/2];s=pr[m*j]+pi[m*j];s=s*(fr[it+j+nv/2]+fi[it+j+nv/2]); poddr=p-q; poddi=s-p-q;fr[it+j+nv/2]=fr[it+j]-poddr;fi[it+j+nv/2]=fi[it+j]-poddi;fr[it+j]=fr[it+j]+poddr;fi[it+j]=fi[it+j]+poddi;}}if (l!=0)for (i=0; i<=n-1; i++){fr[i]=fr[i]/(1.0*n);fi[i]=fi[i]/(1.0*n);}if (il!=0)for (i=0; i<=n-1; i++){pr[i]=sqrt(fr[i]*fr[i]+fi[i]*fi[i]);if (fabs(fr[i])<0.000001*fabs(fi[i])) {if ((fi[i]*fr[i])>0) pi[i]=90.0;else pi[i]=-90.0;}DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDelsepi[i]=atan(fi[i]/fr[i])*360.0/6.283185306;}return;}10.Ronberg 算法计算积分语法:result=integral(double a,double b);参数:a:积分上限b:积分下限我也可以做到..13 / 78function f:积分函数返回值:f 在(a,b)之间的积分值注意:function f(x)需要自行修改,程序中用的是sina(x)/x 需要math.h默认精度要求是1e-5源程序:double f(double x){return sin(x)/x; //在这里插入被积函数}double integral(double a,double b){double h=b-a;double t1=(1+f(b))*h/2.0;int k=1;double r1,r2,s1,s2,c1,c2,t2;loop:double s=0.0;double x=a+h/2.0;while(x<b){s+=f(x);x+=h;}t2=(t1+h*s)/2.0;s2=t2+(t2-t1)/3.0;if(k==1){k++;h/=2.0;t1=t2;s1=s2;goto loop;}c2=s2+(s2-s1)/15.0;if(k==2){c1=c2;k++;h/=2.0;t1=t2;s1=s2;goto loop;}r2=c2+(c2-c1)/63.0;if(k==3){r1=r2; c1=c2;k++;h/=2.0;t1=t2;s1=s2;我也可以做到..14 / 78goto loop;}while(fabs(1-r1/r2)>1e-5){ r1=r2;c1=c2;k++;h/=2.0;t1=t2;s1=s2;goto loop;}return r2;}11.行列式计算语法:result=js(int s[][],int n)参数:s[][]:行列式存储数组n:行列式维数,递归用返回值:行列式值注意:函数中常数N 为行列式维度,需自行定义源程序:int js(s,n)int s[][N],n;{int z,j,k,r,total=0;int b[N][N];/*b[N][N]用于存放,在矩阵s[N][N]中元素s[0]的余子式*/if(n>2){for(z=0;z<n;z++){for(j=0;j<n-1;j++)for(k=0;k<n-1;k++)if(k>=z) b[j][k]=s[j+1][k+1]; elseb[j][k]=s[j+1][k];if(z%2==0) r=s[0][z]*js(b,n-1); /*递归调用*/else r=(-1)*s[0][z]*js(b,n-1);total=total+r;}}else if(n==2)total=s[0][0]*s[1][1]-s[0][1]*s[1][0];return total;我也可以做到..15 / 78}12.求排列组合数语法:result=P(long n,long m); / result=long C(long n,long m);参数:m:排列组合的上系数n:排列组合的下系数返回值:排列组合数注意:符合数学规则:m<=n源程序:long P(long n,long m){long p=1;while(m!=0){p*=n;n--;m--;}return p;}long C(long n,long m){long i,c=1;DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDi=m;while(i!=0){c*=n;n--;i--;}while(m!=0){c/=m;m--;}return c;}13.求某一天星期几语法:result=weekday(int N,int M,int d)参数:N,M,d:年月日,例如:2003,11,4返回值:0:星期天,1 星期一……注意:需要math.h适用于1582 年10 月15 日之后, 因为罗马教皇格里高利十三世在这一天启用新历法.源程序:我也可以做到..16 / 78int weekday(int N,int M,int d){int m,n,c,y,w;m=(M-2)%12;if (M>=3) n=N;else n=N-1;c=n/100;y=n%100;w=(int)(d+floor(13*m/5)+y+floor(y/4)+floor(c/4)-2*c)%7;while(w<0) w+=7;return w;}14.卡特兰(Catalan) 数列原理令h(1)=1,catalan 数满足递归式:h(n)= h(1)*h(n-1) + h(2)*h(n-2) + ... + h(n-1)h(1) (其中n>=2)该递推关系的解为:h(n)=c(2n-2,n-1)/n (n=1,2,3,...)1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440,9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420,24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, …1.括号化问题。

ACM 算法模板

ACM 算法模板

ACM Standard Code LibraryHuang WeiComputer Science and EngineeringAssociation of ProgramingInformation Engineering CollegeHangzhou Dianzi UniversityApril, 2007ACM 算法模板集Contents一.常用函数与STL二.重要公式与定理1. Fibonacci Number2. Lucas Number3. Catalan Number4. Stirling Number(Second Kind)5. Bell Number6. Stirling's Approximation7. Sum of Reciprocal Approximation8. Young Tableau9. 整数划分10. 错排公式11. 三角形内切圆半径公式12. 三角形外接圆半径公式13. 圆內接四边形面积公式14. 基础数论公式三.大数模板四.数论算法1. Greatest Common Divisor最大公约数2. Prime素数判断3. Sieve Prime素数筛法4. Module Inverse模逆元5. Extended Euclid扩展欧几里德算法6. Modular Linear Equation模线性方程(同余方程)7. Chinese Remainder Theorem中国余数定理五.图论算法1. 最小生成树(Kruscal算法)2. 最小生成树(Prim算法)3. 单源最短路径(Bellman-ford算法)4. 单源最短路径(Dijkstra算法)5. 全源最短路径(Folyd算法)6. 拓扑排序7. 网络预流和最大流8. 网络最小费用最大流9. 网络最大流(高度标号预流推进)10. 最大团11. 最大二分图匹配(匈牙利算法)六.几何算法1. 几何模板2. 球面上两点最短距离3. 三点求圆心坐标七.专题讨论1. 树状数组2. 字典树3. 后缀树4. 线段树5. 并查集6. 二叉堆7. 逆序数(归并排序)8. 树状DP9. 欧拉路10. 八数码11. 高斯消元法12. 字符串匹配(KMP算法)13. 全排列,全组合第一章常用函数和STL一.常用函数#include <stdio.h>int getchar( void ); //读取一个字符, 一般用来去掉无用字符char *gets( char *str ); //读取一行字符串#include <stdlib.h>void * malloc( size_t size ); //动态内存分配, 开辟大小为 size 的空间void qsort( void *buf, size_t num, size_t size, int (*compare)(const void *, const void *) ); //快速排序Sample:int compare_ints( const void* a, const void* b ){int* arg1 = (int*) a; int* arg2 = (int*) b;if( *arg1 < *arg2 ) return -1;else if( *arg1 == *arg2 ) return 0;else return 1;}int array[] = { -2, 99, 0, -743, 2, 3, 4 }; int array_size = 7;qsort( array, array_size, sizeof(int), compare_ints );#include <math.h>//求反正弦, arg∈[-1, 1], 返回值∈[-pi/2, +pi/2]double asin( double arg );//求正弦, arg为弧度, 弧度=角度*Pi/180.0, 返回值∈[-1, 1]double sin( double arg );//求e的arg次方double exp( double arg );//求num的对数, 基数为edouble log( double num );//求num的根double sqrt( double num );//求base的exp次方double pow( double base, double exp );#include <string.h>//初始化内存, 常用来初始化数组void* memset( void* buffer, int ch, size_t count );memset( the_array, 0, sizeof(the_array) );//printf是它的变形, 常用来将数据格式化为字符串int sprintf( char *buffer, const char *format, ... );sprintf(s, "%d%d", 123, 4567); //s="1234567"//scanf是它的变形, 常用来从字符串中提取数据int sscanf( const char *buffer, const char *format, ... );Sample:char result[100]="24 hello", str[100]; int num;sprintf( result, "%d %s", num,str );//num=24;str="hello" ;//字符串比较, 返回值<0代表str1<str2, =0代表str1=str2, >0代表str1>str2 int strcmp( const char *str1, const char *str2 );二.常用STL[标准container概要]vector<T> 大小可变的向量, 类似数组的用法, 容易实现删除list<T> 双向链表queue<T> 队列, empty(), front(), pop(), push()stack<T> 栈, empty(), top(), pop(), push()priority_queue<T> 优先队列, empty(), top(), pop(), push()set<T> 集合map<key,val> 关联数组, 常用来作hash映射[标准algorithm摘录]for_each() 对每一个元素都唤起(调用)一个函数find() 查找第一个能与引数匹配的元素replace() 用新的值替换元素, O(N)copy() 复制(拷贝)元素, O(N)remove() 移除元素reverse() 倒置元素sort() 排序, O(N log(N))partial_sort() 部分排序binary_search() 二分查找merge() 合并有序的序列, O(N)[C++ String摘录]copy() 从别的字符串拷贝empty() 判断字符串是否为空erase() 从字符串移除元素find() 查找元素insert() 插入元素length() 字符串长度replace() 替换元素substr() 取子字符串swap() 交换字符串第二章重要公式与定理1.Fibonacci Number0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610 …Formula:2.Lucas Number1, 3, 4, 7, 11, 18, 29, 47, 76, 123...Formula:3.Catalan Number1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012…Formula:Application:1)将n + 2 边形沿弦切割成n个三角形的不同切割数Sample:n = 2;n = 3;2)n + 1个数相乘, 给每两个元素加上括号的不同方法数Sample:n = 2; (1 (2 3)), ((1 2) 3)n = 3; (1 (2 (3 4))), (1 ((2 3) 4)) , ((1 2) (3 4)), ((1 (2 3)) 4), (((1 2) 3) 4)3)n 个节点的不同形状的二叉树数(严《数据结构》P.155)4)从n * n 方格的左上角移动到右下角不升路径数Sample:n = 2;n = 3;4.Stirling Number(Second Kind)S(n, m)表示含n个元素的集合划分为m个集合的情况数或者是n个有标号的球放到m 个无标号的盒子中, 要求无一为空, 其不同的方案数Formula:Special Cases:5.Bell Numbern 个元素集合所有的划分数Formula:6.Stirling's Approximation7.Sum of Reciprocal ApproximationEulerGamma = 0.57721566490153286060651209;8.Young TableauYoung Tableau(杨式图表)是一个矩阵, 它满足条件:如果格子[i, j]没有元素, 则[i+1, j]也一定没有元素如果格子[i, j]有元素a[i, j],则[i+1, j]要么没有元素, 要么a[i+1, j] > a[i, j] Y[n]代表n个数所组成的杨式图表的个数Formula:Sample:n = 3;9.整数划分将整数n分成k份, 且每份不能为空, 任意两种分法不能相同1) 不考虑顺序for(int p=1; p<=n ;p++)for(int i=p; i<=n ;i++)for(int j=k; j>=1 ;j--)dp[i][j] += dp[i-p][j-1];cout<< dp[n][k] <<endl;2) 考虑顺序dp[i][j] = dp[i-k][j-1]; (k=1..i)3) 若分解出来的每个数均有一个上限mdp[i][j] = dp[i-k][ j-1]; (k=1..m)10.错排公式11.三角形内切圆半径公式12.三角形外接圆半径公式13.圆內接四边形面积公式14.基础数论公式1)模取幂2) n的约数的个数若n满足, 则n的约数的个数为第三章大数模板/**** **** **** **** **** ***** Function Name : BigNumber* Description : BigNumber's HPC* Author : HuangWei* Last Edited : 07.4.11**** **** **** **** **** ****/#include <iostream>#include <string>#include <sstream>#include <memory>#include <algorithm>#define BASE 1000 // 基数#define DIG 1100 // 存储using namespace std;class BigNumber{private:int data[DIG]; // 数据区int len; // 记录长度public:BigNumber() {len=1;memset(data,0,sizeof(data));data[0]=1;}BigNumber(int); // 输入默认十进制BigNumber(char*);BigNumber(const BigNumber &);// 类型转换BigNumber & Num_BNum(int); //把一个整数转换成BigNumber型的BigNumber & Str_BNum(char*); //把一个字符串类型的转换成BigNumber型的int Int();string Str();// HPCBigNumber & Add(const BigNumber &);BigNumber & Sub(const BigNumber &);BigNumber & Mul(const BigNumber &);BigNumber & Div(int);BigNumber & Mod(int);BigNumber & operator=(const BigNumber &);int Bigger(const BigNumber &) const;BigNumber operator + (const BigNumber &);BigNumber operator - (const BigNumber &);BigNumber operator * (const BigNumber &);BigNumber operator / (int);BigNumber operator % (int);BigNumber & operator += (const BigNumber &); BigNumber & operator -= (const BigNumber &); BigNumber & operator *= (const BigNumber &); BigNumber & operator /= (int);BigNumber & operator %= (int);};BigNumber & BigNumber::Num_BNum(int b){len=1; memset(data,0,sizeof(data));data[0] = 1;if(b < 0) {b = -b;data[0] = -1;}while(b > 0) {data[ len++ ] = b % BASE;b /= BASE;}return *this;}BigNumber & BigNumber::Str_BNum(char* sb) {int t=0, d=1, b=0, slen=strlen(sb), i;len=1; memset(data,0,sizeof(data));data[0] = 1;if(sb[0] == '-') data[0] = -1, b=1;for(i=slen-1; i>=b ;i--) {while(t >= BASE || d > BASE) {data[ len++ ] = t % BASE;t /= BASE;d = 10;}t += (sb[i]-'0') * d;d *= 10;}while(t > 0) {data[ len++ ] = t % BASE;t /= BASE;}return *this;}int BigNumber::Int(){istringstream sin;int v;sin.str( this->Str() );sin >> v;return v;} //这个函数的用法还是第一次看到,没看懂string BigNumber::Str(){int i,base_len=0;ostringstream sout;if(len == 1) {sout << '0';//sout << endl;return sout.str();}if(data[0] < 0) sout << "-";sout << data[len-1];i = BASE;while(i > 1) {base_len++;i /= 10;}for(i=len-2; i>0 ;i--) {sout.width(base_len);sout.fill('0');sout << data[i];}//sout << endl;return sout.str();} //这个函数也没有看懂BigNumber::BigNumber(int b){this->Num_BNum(b);}BigNumber::BigNumber(char* sb){this->Str_BNum(sb);}// -1 a<b, 0 a==b, 1 a>bBigNumber::BigNumber(const BigNumber & b){len = b.len; memcpy(data,b.data,sizeof(data));}int BigNumber::Bigger(const BigNumber & b) const {int i,flag;if(data[0] ==1 && b.data[0] ==1) flag = 1;else if(data[0] ==1 && b.data[0] ==-1) return 1;else if(data[0] ==-1 && b.data[0] ==1) return -1;else flag = -1;if(len > b.len) return flag;else if(len == b.len) {for(i=len-1; i>0 ;i--)if(data[i] > b.data[i]) return flag;}if(i == 0) return 0;return -flag;} //比较函数BigNumber & BigNumber::Add(const BigNumber & b) {int i;if(data[0] * b.data[0] != 1) {data[0] = -data[0];Sub(b);data[0] = -data[0];return *this;}len= len > b.len ? len : b.len;for(i=1; i<len ;i++) {data[i] += b.data[i];if(data[i] >= BASE) {data[i+1]++;data[i] -= BASE;}}if(data[i] > 0) len = i+1;return *this;} //加上b这个大数BigNumber & BigNumber::Sub(const BigNumber & b) {int i;if(data[0] * b.data[0] != 1) {data[0] = -data[0];Add(b);data[0] = -data[0];return *this;}len= len > b.len ? len : b.len;for(i=1; i<len ;i++) {data[i] -= b.data[i];if(data[i] < 0) {data[i+1]--;data[i] += BASE;}}if(data[len] < 0) {for(i=0; i<=len ;i++)data[i] = -data[i];for(i=1; i<len ;i++)if(data[i] < 0) {data[i+1]--;data[i] += BASE;}}while(data[len-1] == 0) len--;return *this;}BigNumber & BigNumber::Mul(const BigNumber & b) {BigNumber bt;int i,j,up;int temp,temp1;bt.data[0] = data[0] * b.data[0];for(i=1; i<len ;i++) {up = 0;for(j=1; j<b.len ;j++) {temp = data[i] * b.data[j] + bt.data[i+j-1] + up;if(temp >= BASE) {temp1 = temp % BASE;up = temp / BASE;bt.data[i+j-1] = temp1;}else {up = 0;bt.data[i+j-1] = temp;}}if(up != 0) bt.data[i+j-1] = up;}bt.len = i+j;while(bt.data[bt.len-1] == 0) bt.len--;*this=bt;return *this;}BigNumber & BigNumber::Div(int b){BigNumber bt;int i,down = 0;if(b < 0) bt.data[0] = -data[0] , b = -b;else bt.data[0] = data[0];for(i=len-1; i>=1 ;i--) {bt.data[i] = (data[i] + down * BASE) / b;down = data[i] + down * BASE - bt.data[i] * b;}bt.len = len;while(bt.data[bt.len-1] == 0) bt.len--;*this=bt;return *this;}BigNumber & BigNumber::Mod(int b){int temp = 0, up = 0, i;for(i=len-1; i>=1 ;i--) {temp = data[i];temp += up * BASE;up = temp % b;}if(data[0] < 0) up = -up;*this = up;return *this;}BigNumber & BigNumber::operator = (const BigNumber & b) {len = b.len; memcpy(data,b.data,sizeof(data)); return *this;}BigNumber BigNumber::operator + (const BigNumber & b) {BigNumber bt=*this; return bt.Add(b);}BigNumber BigNumber::operator - (const BigNumber & b) {BigNumber bt=*this; return bt.Sub(b);}BigNumber BigNumber::operator * (const BigNumber & b) {BigNumber bt=*this; return bt.Mul(b);}BigNumber BigNumber::operator / (int b){BigNumber bt=*this; return bt.Div(b);}BigNumber BigNumber::operator % (int b){BigNumber bt=*this; return bt.Mod(b);}BigNumber & BigNumber::operator += (const BigNumber & b) {return this->Add(b);}BigNumber & BigNumber::operator -= (const BigNumber & b) {return this->Sub(b);}BigNumber & BigNumber::operator *= (const BigNumber & b) {return this->Mul(b);}BigNumber & BigNumber::operator /= (int b){return this->Div(b);}BigNumber & BigNumber::operator %= (int b){return this->Mod(b);}第四章数论算法1.Greatest Common Divisor最大公约数int GCD(int x, int y){int t;while(y > 0) {t = x % y;x = y;y = t;}return x;}2.Prime素数判断bool is_prime(int u){if(u == 0 || u == 1) return false;if(u == 2) return true;if(u%2 == 0) return false;for(int i=3; i <= sqrt(u) ;i+=2)if(u%i==0) return false;return true;}3.Sieve Prime素数筛法const int M = 1000; // M : sizebool mark[M]; // true : prime numbervoid sieve_prime(){memset(mark, true, sizeof(mark));mark[0] = mark[1] = false;for(int i=2; i <= sqrt(M) ;i++) {if(mark[i]) {for(int j=i*i; j < M ;j+=i)mark[j] = false;}}}4.Module Inverse模逆元// ax ≡ 1 (mod n)int Inv(int a, int n){int d, x, y;d = extended_euclid(a, n, x, y);if(d == 1) return (x%n + n) % n;else return -1; // no solution}5.Extended Euclid扩展欧几里德算法//如果GCD(a,b) = d, 则存在x, y, 使d = ax + by// extended_euclid(a, b) = ax + byint extended_euclid(int a, int b, int &x, int &y){int d;if(b == 0) {x = 1; y = 0; return a;}d = extended_euclid(b, a % b, y, x);y -= a / b * x;return d;}6.Modular Linear Equation模线性方程(同余方程) //如果GCD(a, b)不能整除c, 则ax + by = c 没有整数解// ax ≡ b (mod n) n > 0//上式等价于二元一次方程ax – ny = bvoid modular_linear_equation(int a, int b, int n){int d, x, y, x0;d = extended_euclid(a, n, x, y);if( b%d == 0) {x0 = ( x*(b/d) ) % n; // x0 : basic solutionint ans = n;for(int i=0; i < d ;i++) {ans = ( x0 + i*(n/d) ) % n;cout << ans << endl;}}else cout << "no solution" << endl;}7.Chinese Remainder Theorem中国余数定理// x ≡ b[i] (mod w[i]), i∈[1, len-1]// 前提条件w[i] > 0, 且w[]中任意两个数互质int chinese_remainder(int b[], int w[], int len){int i, d, x, y, m, n;x = 0; n = 1;for(i=0; i < len ;i++) n *= w[i];for(i=0; i < len ;i++) {m = n / w[i] ;d = extended_euclid(w[i], m, x, y);x = (x + y*m*b[i]) % n;}return (n + x%n) % n;}第五章图论算法1.最小生成树(Kruscal算法)/**** **** **** **** **** ***** Function Name : 最小生成树(Kruscal算法)* Description : ZJU 1203 Swordfish O(E*LogE)**** **** **** **** **** ****/#include <iostream>#include <algorithm>#include <cstdio>#include <cmath>using namespace std;struct struct_edges{int bv,tv; //bv 起点 tv 终点double w; //权值};struct_edges edges[10100]; //边集struct struct_a{double x;double y;};struct_a arr_xy[101];int point[101],n,e; //n 顶点数, e 边数(注意是无向网络)double sum;int kruscal_f1(int point[], int v){int i = v;while(point[i] > 0) i = point[i];return i;}bool UDlesser(struct_edges a, struct_edges b){return a.w < b.w;}void kruscal() //只需要准备好n,e,递增的边集edges[]即可使用{int v1,v2,i,j;for(i=0; i<n ;i++) point[i]=0;i = j = 0;while(j<n-1 && i<e) {v1 = kruscal_f1(point, edges[i].bv);v2 = kruscal_f1(point, edges[i].tv);if(v1 != v2) {sum += edges[i].w; //注意sum初始为0point[v1]=v2;j++;}i++;}}int main(){int k,i,j;cin>>n;k=0;while(n != 0) {sum=0;k++;for(i=0; i<n ;i++)cin>>arr_xy[i].x>>arr_xy[i].y;e=0;for(i=0; i<n ;i++) //从0开始计数for(j=i+1; j<n ;j++) //注意是无向网络{if(i == j) continue;edges[e].bv=i;edges[e].tv=j;edges[e].w=sqrt((arr_xy[i].x-arr_xy[j].x)*(arr_xy[i].x-arr_xy[j].x)+( arr_xy[i].y-arr_xy[j].y)*(arr_xy[i].y-arr_xy[j].y));e++;}sort(edges,edges+e,UDlesser); //得到一个递增的边集,注意是从0开始计数kruscal();printf("Case #%d:\n",k); //cout<<"Case #"<<k<<":"<<endl;printf("The minimal distance is: %.2f\n",sum); //输出sumcin>>n;if(n != 0) printf("\n");}}2.最小生成树(Prim算法)/**** **** **** **** **** ***** Function Name : 最小生成树(Prim算法)* Description : ZJU 1203 Swordfish O(N^2)**** **** **** **** **** ****/#include <iostream>#include <cmath>#include <cstdio>using namespace std;double sum, arr_list[101][101], min;int i, j, k=0, n;struct struct_a{float x;float y;};struct_a arr_xy[101];struct struct_b{int point;float lowcost;};struct_b closedge[101];void prim(int n) //prim 需要准备:n顶点数 arr_list[][]顶点的邻接矩阵也是从0开始计数{int i,j,k;k=0;for(j=0; j<n ;j++) {if(j != k) {closedge[j].point = k;closedge[j].lowcost = arr_list[k][j];}}closedge[k].lowcost=0;for(i=0; i<n ;i++) {min=10000;for(j=0; j<n ;j++) {if (closedge[j].lowcost != 0 && closedge[j].lowcost < min) {k = j;min = closedge[j].lowcost;}}sum += closedge[k].lowcost; //不要改成sum+=min; sum即为所求值 closedge[k].lowcost = 0;for(j=0; j<n ;j++) {if(arr_list[k][j] < closedge[j].lowcost) {closedge[j].point = k;closedge[j].lowcost = arr_list[k][j];}}}}/*arr_list[][]= Wij 如果Vi, Vj有边0 如果i=j无限大如果没有边*/int main(){cin>>n;while(n != 0) {sum=0;k++;for(i=0; i<n ;i++)cin>>arr_xy[i].x>>arr_xy[i].y;for(i=0; i<n ;i++)for(j=0; j<n ;j++) //得到邻接矩阵arr_list[][]arr_list[i][j]=arr_list[j][i]=sqrt((arr_xy[i].x-arr_xy[j].x)*(arr_xy[i].x-arr_xy[j].x)+(arr_xy[i].y-arr_xy[j].y)*(arr_xy[i].y-arr_xy[j].y));prim(n);cout<<"Case #"<<k<<":"<<endl;printf("The minimal distance is: %.2f\n",sum);cin>>n;if(n!=0) printf("\n");}}3.单源最短路径(Bellman-ford算法)/**** **** **** **** **** ***** Function Name : 单源最短路径(Bellman-ford算法)* Description : 可允许有负权**** **** **** **** **** ****/#include <stdio.h>#define MAX 100#define MAXNUM 1000000typedef struct graphnode{int vexnum; //顶点数int arcnum; //边数int gra[MAX][MAX]; //图}Graph;Graph *G;//arc数组中存储的第一个顶点到其他顶点的最短路径//结果存在dis数组中int dis[MAX];int arc[MAX][MAX];void bellman(Graph *G){int i,j;bool sign;for(i=0; i < G->vexnum ;i++) dis[i]=MAXNUM;dis[1] = 0;sign = true;for(i=1; i < G->vexnum ;i++) {sign = false;for(j=0; j < G->arcnum ;j++) {if(dis[ arc[j][0] ] < MAXNUM&& dis[ arc[j][1] ] > dis[ arc[j][0] ] + G->gra[ arc[j][0] ][ arc[j][1] ]) {dis[ arc[j][1] ]=dis[ arc[j][0] ] + G->gra[ arc[j][0] ][ arc[j][1] ];sign = true;}}}return;}4.单源最短路径(Dijkstra算法)/**** **** **** **** **** ***** Function Name : 单源最短路径 (Dijkstra算法)* Description : 贪心, O(N^2), 不能有负权**** **** **** **** **** ****/int matrix[200][200],n; //matrix[][], 30000表示无限大,即无边.否则为有边,其值为边的权值void Dijkstra(int x,int y) //起点Vx 终点Vy{int i,j,k,path[40000],mark[40000];int min,dist[40000];for(i=1;i<=n;i++) {mark[i] = 0;dist[i] = matrix[x][i];path[i] = x;}mark[x] = 1;do {min=30000;k=0;for(i=1;i<=n;i++)if(mark[i]==0 && dist[i]<min) {min = dist[i];k = i;}if(k) {mark[k] = 1;for(i=1;i<=n;i++)if(matrix[k][i]<30000 && min+matrix[k][i]<dist[i]) {dist[i] = min + matrix[k][i];path[i] = k;}}}while(k);cout<<dist[y]<<endl; //dist[y] 的值就是从Vx 到 Vy 的最短路径值//如果希望得到路径,加入如下代码:do {cout<<k<<"<--";k = path[k];}while(k!=x);cout<<x<<endl;}5.全源最短路径(Folyd算法)/**** **** **** **** **** ***** Function Name : 全源最短路径(Folyd算法)* Description : DP, O(N^3)**** **** **** **** **** ****///初始化//min_graph[i][j]=graph[i][j];//path[i][j]=j;void Floyd(){int i,j,k;for(k=0;k<vertex_number;k++) {for(i=0;i<vertex_number;i++) {for(j=0;j<vertex_number;j++) {if((graph[i][k]==-1) || (graph[k][j]==-1)) continue;if((min_graph[i][j]==-1) || (min_graph[i][j] > graph[i][k]+graph[k][j])) {min_graph[i][j] = graph[i][k]+graph[k][j]; /*最短路径值*/path[i][j] = k; /*最短路径*/}}}}}6.拓扑排序/**** **** **** **** **** ***** Function Name : 拓扑排序**** **** **** **** **** ****///degree[] 每个结点的入度//f[] 每个结点所在的层void Toplogical_sort(){int i,j;bool p=true;top=0;while(p) {p=false;top++;for(i=1;i<=n;i++)if(degree[i]==0) {p=true;f[i]=top;}for(i=1;i<=n;i++)if(f[i]==top) {for(j=1;j<=n;j++)if(map[i][j]) degree[j]--;degree[i]=-1;}}top--;}7.网络预流和最大流int rel[1000][10000]; //全局变量int pre[1000];//计算网络流//如果是二分图的匹配, 可以先对其进行网络预流以简化后续的查找int pre_flow(int n,vector<int> * v){int ret = 0;int i,j,t,t1;for(i = 0 ; i < v[0].size() ; i++){t = v[0][i]; //t是与节点0相邻接的点for(j = 0 ; j < v[t].size() ; j++){t1 = v[t][j]; //与t相邻接的点if(rel[t1][n - 1] > 0){ret++;rel[0][t]--, rel[t][0]++;rel[t][t1]--, rel[t1][t]++;rel[t1][n - 1]--, rel[n - 1][t1]++;break;}}}return ret;}/*网络中求最大流参数含义: n代表网络中节点数,第0节点为源点, 第n-1节点为汇点rel是个二维数组, rel[i][j]代表从节点i到节点j的流量v[]是一个节点数组, v[i]包含与节点i相邻接的所有节点返回值: 最大流量*/int max_flow(int n,vector<int> * v){int ret = 0,i;int t,t1,tm;queue<int> q;const int Infinite = 2000000000;while(1){for(t = 0 ; t < n ; t++) pre[t] = -1;while(!q.empty()) q.pop();q.push(0);while(!q.empty()){ //find a augmenting path using breath-first searcht = q.front();q.pop();if(t == n - 1) break; //到达汇点for(i = 0 ; i < v[t].size() ; i++){ //对于t相邻接的所有点查找可行路径 t1 = v[t][i];if(rel[t][t1] > 0 && pre[t1] == -1){pre[t1] = t;q.push(t1);}}}if(q.empty() && t != n - 1) break;tm = Infinite; //此处寻找路径最小值在二分图中可省略while(t != 0){ //find the minimal num in the patht1 = pre[t];if(rel[t1][t] < tm) tm = rel[t1][t];t = t1;}// tm = 1; //二分图中t = n - 1;while(t != 0){ //change the relationt1 = pre[t];rel[t1][t] -= tm;rel[t][t1] += tm;t = t1;}ret += tm;}return ret;}8.网络最小费用最大流/**** **** **** **** **** ****网络中最小费用最大流参数含义: np代表网络中的总节点数, v是网络节点的邻接表cost为最后求得的最小费用, mf为求得的最大流算法: 初始最小费用及最大流均为0,不断寻找可增广路增广路对应的单位费用最小并且可流修改残留网络及cost,mf. 直到无可增广路为止。

ACM大赛必备_常用函数整理_ACM模板

ACM大赛必备_常用函数整理_ACM模板

目录一、数学问题 (4)1.精度计算——大数阶乘 (4)2.精度计算——乘法(大数乘小数) (4)3.精度计算——乘法(大数乘大数) (5)4.精度计算——加法 (6)5.精度计算——减法 (7)6.任意进制转换 (8)7.最大公约数、最小公倍数 (9)8.组合序列 (10)9.快速傅立叶变换(FFT) (10)10.Ronberg 算法计算积分 (12)11.行列式计算 (14)12.求排列组合数 (15)13.求某一天星期几 (15)14.卡特兰(Catalan) 数列原理 (16)15.杨辉三角 (16)16.全排列 (17)17.匈牙利算法----最大匹配问题 (18)18.最佳匹配KM 算法 (20)二、字符串处理 (22)1.字符串替换 (22)2.字符串查找 (23)3.字符串截取 (24)4.LCS-最大公共子串长度 (24)5.LCS-最大公共子串长度 (25)6.数字转换为字符 (26)三、计算几何 (27)1.叉乘法求任意多边形面积 (27)2.求三角形面积 (27)3.两矢量间角度 (28)4.两点距离(2D、3D) (28)5.射向法判断点是否在多边形内部 (29)6.判断点是否在线段上 (30)7.判断两线段是否相交 (31)8.判断线段与直线是否相交 (32)9.点到线段最短距离 (32)10.求两直线的交点 (33)11.判断一个封闭图形是凹集还是凸集 (34)12.Graham 扫描法寻找凸包 (35)13.求两条线段的交点 (36)四、数论 (37)1.x 的二进制长度 (37)2.返回x 的二进制表示中从低到高的第i 位 (38)3.模取幂运算 (38)4.求解模线性方程 (39)5.求解模线性方程组(中国余数定理) (39)6.筛法素数产生器 (40)7.判断一个数是否素数 (41)8.求距阵最大和 (42)8.求一个数每一位相加之和 (43)10.质因数分解 (43)11.高斯消元法解线性方程组 (44)五、图论 (45)1.Prim 算法求最小生成树................................................. 45 2.Dijkstra 算法求单源最短路径.. (46)3.Bellman-ford 算法求单源最短路径 (47)4.Floyd-Warshall 算法求每对节点间最短路径 (48)5.解欧拉图 (49)六、排序/查找 (50)1.快速排序 (50)2.希尔排序 (51)3.选择法排序 (52)4.二分查找 (52)七、数据结构 (53)1.顺序队列 (53)2.顺序栈 (56)3.链表 (59)4.链栈 (63)5.二叉树 (66)八、高精度运算专题 (68)1.专题函数说明 (68)2.高精度数比较 (69)3.高精度数加法 (69)4.高精度数减法 (70)5.高精度乘10 (71)6.高精度乘单精度 (71)7.高精度乘高精度 (72)8.高精度除单精度 (72)9.高精度除高精度 (73)九、标准模板库的使用 (74)1.计算求和 (74)2.求数组中的最大值 (76)3. sort 和qsort (76)十、其他 (78)1.运行时间计算 (78)一、数学问题1.精度计算——大数阶乘语法:int result=factorial(int n);参数:n:n 的阶乘返回值:阶乘结果的位数注意:本程序直接输出n!的结果,需要返回结果请保留long a[] 需要math.h源程序:int factorial(int n){long a[10000];int i,j,l,c,m=0,w;a[0]=1;for(i=1;i<=n;i++){c=0;for(j=0;j<=m;j++){a[j]=a[j]*i+c;c=a[j]/10000;a[j]=a[j]%10000;}if(c>0) {m++;a[m]=c;}}w=m*4+log10(a[m])+1;printf("\n%ld",a[m]);for(i=m-1;i>=0;i--) printf("%4.4ld",a[i]);return w;}我也可以做到..5 / 782.精度计算——乘法(大数乘小数)语法:mult(char c[],char t[],int m);参数:c[]:被乘数,用字符串表示,位数不限t[]:结果,用字符串表示m:乘数,限定10 以内返回值:null注意:需要string.h源程序:void mult(char c[],char t[],int m){int i,l,k,flag,add=0;char s[100];l=strlen(c);for (i=0;i<l;i++)s[l-i-1]=c[i]-'0';for (i=0;i<l;i++){k=s[i]*m+add;if (k>=10) {s[i]=k%10;add=k/10;flag=1;} else{s[i]=k;flag=0;add=0;}}if (flag) {l=i+1;s[i]=add;} else l=i;for (i=0;i<l;i++)t[l-1-i]=s[i]+'0'; t[l]='\0';}3.精度计算——乘法(大数乘大数)语法:mult(char a[],char b[],char s[]);参数:a[]:被乘数,用字符串表示,位数不限b[]:乘数,用字符串表示,位数不限t[]:结果,用字符串表示返回值:null注意:空间复杂度为o(n^2)需要string.h源程序:void mult(char a[],char b[],char s[]){我也可以做到..6 / 78int i,j,k=0,alen,blen,sum=0,res[65][65]={0},flag=0; char result[65];alen=strlen(a);blen=strlen(b);for (i=0;i<alen;i++)for (j=0;j<blen;j++) res[i][j]=(a[i]-'0')*(b[j]-'0');for (i=alen-1;i>=0;i--){for (j=blen-1;j>=0;j--) sum=sum+res[i+blen-j-1][j]; result[k]=sum%10;k=k+1;sum=sum/10;}for (i=blen-2;i>=0;i--){for (j=0;j<=i;j++) sum=sum+res[i-j][j];result[k]=sum%10;k=k+1;sum=sum/10;}if (sum!=0) {result[k]=sum;k=k+1;}for (i=0;i<k;i++) result[i]+='0';for (i=k-1;i>=0;i--) s[i]=result[k-1-i];s[k]='\0';while(1){if (strlen(s)!=strlen(a)&&s[0]=='0')strcpy(s,s+1);elsebreak;}}4.精度计算——加法语法:add(char a[],char b[],char s[]);参数:a[]:被加数,用字符串表示,位数不限b[]:加数,用字符串表示,位数不限s[]:结果,用字符串表示返回值:null注意:空间复杂度为o(n^2)我也可以做到..7 / 78需要string.h源程序:void add(char a[],char b[],char back[]){int i,j,k,up,x,y,z,l;char *c;if (strlen(a)>strlen(b)) l=strlen(a)+2; else l=strlen(b)+2; c=(char *) malloc(l*sizeof(char));i=strlen(a)-1;j=strlen(b)-1;k=0;up=0;while(i>=0||j>=0){if(i<0) x='0'; else x=a[i];if(j<0) y='0'; else y=b[j];z=x-'0'+y-'0';if(up) z+=1;if(z>9) {up=1;z%=10;} else up=0;c[k++]=z+'0';i--;j--;}if(up) c[k++]='1';i=0;c[k]='\0';for(k-=1;k>=0;k--)back[i++]=c[k];back[i]='\0';}5.精度计算——减法语法:sub(char s1[],char s2[],char t[]);参数:s1[]:被减数,用字符串表示,位数不限s2[]:减数,用字符串表示,位数不限t[]:结果,用字符串表示返回值:null注意:默认s1>=s2,程序未处理负数情况需要string.h源程序:void sub(char s1[],char s2[],char t[])我也可以做到..8 / 78{int i,l2,l1,k;l2=strlen(s2);l1=strlen(s1);t[l1]='\0';l1--;for (i=l2-1;i>=0;i--,l1--){if (s1[l1]-s2[i]>=0)t[l1]=s1[l1]-s2[i]+'0';else{t[l1]=10+s1[l1]-s2[i]+'0';s1[l1-1]=s1[l1-1]-1;}}k=l1;while(s1[k]<0) {s1[k]+=10;s1[k-1]-=1;k--;}while(l1>=0) {t[l1]=s1[l1];l1--;}loop:if (t[0]=='0') {l1=strlen(s1);for (i=0;i<l1-1;i++) t[i]=t[i+1];t[l1-1]='\0';goto loop;}if (strlen(t)==0) {t[0]='0';t[1]='\0';}}6.任意进制转换语法:conversion(char s1[],char s2[],char t[]);参数:s[]:转换前的数字s2[]:转换后的数字d1:原进制数d2:需要转换到的进制数返回值:null注意:高于9 的位数用大写'A'~'Z'表示,2~16 位进制通过验证源程序:void conversion(char s[],char s2[],long d1,long d2){我也可以做到..9 / 78long i,j,t,num;char c;num=0;for (i=0;s[i]!='\0';i++){if (s[i]<='9'&&s[i]>='0') t=s[i]-'0'; else t=s[i]-'A'+10;num=num*d1+t;}i=0;while(1){t=num%d2;if (t<=9) s2[i]=t+'0'; else s2[i]=t+'A'-10;num/=d2;if (num==0) break;i++;}for (j=0;j<i/2;j++){c=s2[j];s2[j]=s[i-j];s2[i-j]=c;}s2[i+1]='\0';}7.最大公约数、最小公倍数语法:resulet=hcf(int a,int b)、result=lcd(int a,int b)参数:a:int a,求最大公约数或最小公倍数b:int b,求最大公约数或最小公倍数返回值:返回最大公约数(hcf)或最小公倍数(lcd)注意:lcd 需要连同hcf 使用源程序:int hcf(int a,int b){int r=0;while(b!=0){r=a%b;a=b;b=r;}return(a);我也可以做到..10 / 78}lcd(int u,int v,int h){return(u*v/h);}8.组合序列语法:m_of_n(int m, int n1, int m1, int* a, int head)参数:m:组合数C 的上参数n1:组合数C 的下参数m1:组合数C 的上参数,递归之用*a:1~n 的整数序列数组head:头指针返回值:null注意:*a 需要自行产生初始调用时,m=m1、head=0调用例子:求C(m,n)序列:m_of_n(m,n,m,a,0);源程序:void m_of_n(int m, int n1, int m1, int* a, int head){int i,t;if(m1<0 || m1>n1) return;if(m1==n1){return;}m_of_n(m,n1-1,m1,a,head); // 递归调用t=a[head];a[head]=a[n1-1+head];a[n1-1+head]=t;m_of_n(m,n1-1,m1-1,a,head+1); // 再次递归调用t=a[head];a[head]=a[n1-1+head];a[n1-1+head]=t;}9.快速傅立叶变换(FFT)语法:kkfft(double pr[],double pi[],int n,int k,double fr[],double fi[],intl,int il);参数:我也可以做到..11 / 78pr[n]:输入的实部pi[n]:数入的虚部n,k:满足n=2^kfr[n]:输出的实部fi[n]:输出的虚部l:逻辑开关,0 FFT,1 ifFTil:逻辑开关,0 输出按实部/虚部;1 输出按模/幅角返回值:null注意:需要math.h源程序:void kkfft(pr,pi,n,k,fr,fi,l,il)int n,k,l,il;double pr[],pi[],fr[],fi[];{int it,m,is,i,j,nv,l0; double p,q,s,vr,vi,poddr,poddi;for (it=0; it<=n-1; it++){m=it; is=0;for (i=0; i<=k-1; i++){j=m/2; is=2*is+(m-2*j); m=j;}fr[it]=pr[is]; fi[it]=pi[is];}pr[0]=1.0; pi[0]=0.0;p=6.283185306/(1.0*n);pr[1]=cos(p); pi[1]=-sin(p);if (l!=0) pi[1]=-pi[1];for (i=2; i<=n-1; i++){p=pr[i-1]*pr[1];q=pi[i-1]*pi[1];s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]);pr[i]=p-q; pi[i]=s-p-q;}for (it=0; it<=n-2; it=it+2){vr=fr[it]; vi=fi[it];fr[it]=vr+fr[it+1]; fi[it]=vi+fi[it+1];fr[it+1]=vr-fr[it+1]; fi[it+1]=vi-fi[it+1]; }m=n/2; nv=2;for (l0=k-2; l0>=0; l0--){我也可以做到..12 / 78m=m/2; nv=2*nv;for (it=0; it<=(m-1)*nv; it=it+nv)for (j=0; j<=(nv/2)-1; j++){p=pr[m*j]*fr[it+j+nv/2];q=pi[m*j]*fi[it+j+nv/2];s=pr[m*j]+pi[m*j];s=s*(fr[it+j+nv/2]+fi[it+j+nv/2]); poddr=p-q; poddi=s-p-q;fr[it+j+nv/2]=fr[it+j]-poddr;fi[it+j+nv/2]=fi[it+j]-poddi;fr[it+j]=fr[it+j]+poddr;fi[it+j]=fi[it+j]+poddi;}}if (l!=0)for (i=0; i<=n-1; i++){fr[i]=fr[i]/(1.0*n);fi[i]=fi[i]/(1.0*n);}if (il!=0)for (i=0; i<=n-1; i++){pr[i]=sqrt(fr[i]*fr[i]+fi[i]*fi[i]);if (fabs(fr[i])<0.000001*fabs(fi[i])) {if ((fi[i]*fr[i])>0) pi[i]=90.0;else pi[i]=-90.0;}elsepi[i]=atan(fi[i]/fr[i])*360.0/6.283185306;}return;}10.Ronberg 算法计算积分语法:result=integral(double a,double b);参数:a:积分上限b:积分下限我也可以做到..13 / 78function f:积分函数返回值:f 在(a,b)之间的积分值注意:function f(x)需要自行修改,程序中用的是sina(x)/x 需要math.h默认精度要求是1e-5源程序:double f(double x){return sin(x)/x; //在这里插入被积函数}double integral(double a,double b){double h=b-a;double t1=(1+f(b))*h/2.0;int k=1;double r1,r2,s1,s2,c1,c2,t2;loop:double s=0.0;double x=a+h/2.0;while(x<b){s+=f(x);x+=h;}t2=(t1+h*s)/2.0;s2=t2+(t2-t1)/3.0;if(k==1){k++;h/=2.0;t1=t2;s1=s2;goto loop;}c2=s2+(s2-s1)/15.0;if(k==2){c1=c2;k++;h/=2.0;t1=t2;s1=s2;goto loop;}r2=c2+(c2-c1)/63.0;if(k==3){r1=r2; c1=c2;k++;h/=2.0;t1=t2;s1=s2;我也可以做到..14 / 78goto loop;}while(fabs(1-r1/r2)>1e-5){ r1=r2;c1=c2;k++;h/=2.0;t1=t2;s1=s2;goto loop;}return r2;}11.行列式计算语法:result=js(int s[][],int n)参数:s[][]:行列式存储数组n:行列式维数,递归用返回值:行列式值注意:函数中常数N 为行列式维度,需自行定义源程序:int js(s,n)int s[][N],n;{int z,j,k,r,total=0;int b[N][N];/*b[N][N]用于存放,在矩阵s[N][N]中元素s[0]的余子式*/if(n>2){for(z=0;z<n;z++){for(j=0;j<n-1;j++)for(k=0;k<n-1;k++)if(k>=z) b[j][k]=s[j+1][k+1]; elseb[j][k]=s[j+1][k];if(z%2==0) r=s[0][z]*js(b,n-1); /*递归调用*/else r=(-1)*s[0][z]*js(b,n-1);total=total+r;}}else if(n==2)total=s[0][0]*s[1][1]-s[0][1]*s[1][0];return total;我也可以做到..15 / 78}12.求排列组合数语法:result=P(long n,long m); / result=long C(long n,long m);参数:m:排列组合的上系数n:排列组合的下系数返回值:排列组合数注意:符合数学规则:m<=n源程序:long P(long n,long m){long p=1;while(m!=0){p*=n;n--;m--;}return p;}long C(long n,long m){long i,c=1;i=m;while(i!=0){c*=n;n--;i--;}while(m!=0){c/=m;m--;}return c;}13.求某一天星期几语法:result=weekday(int N,int M,int d)参数:N,M,d:年月日,例如:2003,11,4返回值:0:星期天,1 星期一……注意:需要math.h适用于1582 年10 月15 日之后, 因为罗马教皇格里高利十三世在这一天启用新历法.源程序:我也可以做到..16 / 78int weekday(int N,int M,int d){int m,n,c,y,w;m=(M-2)%12;if (M>=3) n=N;else n=N-1;c=n/100;y=n%100;w=(int)(d+floor(13*m/5)+y+floor(y/4)+floor(c/4)-2*c)%7;while(w<0) w+=7;return w;}14.卡特兰(Catalan) 数列原理令h(1)=1,catalan 数满足递归式:h(n)= h(1)*h(n-1) + h(2)*h(n-2) + ... + h(n-1)h(1) (其中n>=2)该递推关系的解为:h(n)=c(2n-2,n-1)/n (n=1,2,3,...)1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440,9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420,24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, …1.括号化问题。

ACM之Java输入输出

ACM之Java输入输出

ACM之Java输⼊输出⼀、Java之ACM注意点1. 类名称必须采⽤public class Main⽅式命名2. 在有些OJ系统上,即便是输出的末尾多了⼀个“ ”,程序可能会输出错误,所以在我看来好多OJ系统做的是⾮常之垃圾3. 有些OJ上的题⽬会直接将OI上的题⽬拷贝过来,所以即便是题⽬中有输⼊和输出⽂件,可能也不需要,因为在OJ系统中⼀般是采⽤标准输⼊输出,不需要⽂件4. 在有多⾏数据输⼊的情况下,⼀般这样处理,static Scanner in = new Scanner(System.in);while(in.hasNextInt())或者是while(in.hasNext())5. 有关System.nanoTime()函数的使⽤,该函数⽤来返回最准确的可⽤系统计时器的当前值,以毫微秒为单位。

long startTime = System.nanoTime();// ... the code being measured ...long estimatedTime = System.nanoTime() - startTime;这⾥第⼀次⽤java玩acm的注意:1、主类所在类的类名⼀定是Main,即是main⽅法所在类2、循环输⼊的问题,在C++我们可以⽤while(scanf("%d",&a)!=EOF),但是在java中我们⽤的是扫描类的hasNext()函数来判断是否结束输⼊,另外注意导⼊Scanner类⼆、Java之输⼊输出处理由于ACM竞赛题⽬的输⼊数据和输出数据⼀般有多组(不定),并且格式多种多样,所以,如何处理题⽬的输⼊输出是对⼤家的⼀项最基本的要求。

这也是困扰初学者的⼀⼤问题。

1. 输⼊:格式1:Scanner sc = new Scanner (new BufferedInputStream(System.in));格式2:Scanner sc = new Scanner (System.in);在读⼊数据量⼤的情况下,格式1的速度会快些。

Java的ACM输入输出格式

Java的ACM输入输出格式

Java的ACM输⼊输出格式ACM 格式1. 类名称必须采⽤ public class Main ⽅式命名2. 多组输⼊,读取到⽂件尾Scanner scan =new Scanner(System.in);while(scan.hasNext()){// 读整数int n = scan.nextInt();// 读⼩数double d = scan.nextDouble();// 读字符串String s = scan.next();// 读⼀整⾏String s = xLine();// 读⼤数BigInteger bi = scan.nextBigInteger();}// 或者 scan.hasNextInt()// 或者 scan.hasNextDouble()// 或者 scan.hasNextLine()3. 当数据较多时,可以采⽤更快的⽅式import java.io.BufferedInputStream;Scanner scan =new Scanner(new BufferedInputStream(System.in));4. Java 运算⼤数import java.math.BigInteger;//操作⼤整数import java.math.BigDecimal;//操作⼤⼩数import java.io.BufferedInputStream;import java.util.Scanner;import java.util.Arrays;public class Main{public static void main(String []args){BigInteger a,b,ans;Scanner scan=new Scanner(System.in);a=scan.nextBigInteger();b=scan.nextBigInteger();ans=a.add(b);//ans=a+b;ans=a.subtract(b);//ans=a-bans=a.mod(b);//ans=a%bans=a.divide(b);//ans=a/bans=a.max(b);ans=a.min(b); ans=a.multiply(b);}}next() 与 nextLine() 的区别:1. next() ⼀定要读取到有效字符后才可以结束输⼊,对输⼊有效字符之前遇到的空格键、Tab 键或 Enter 键等结束符,next() ⽅法会⾃动将其去掉,只有在输⼊有效字符之后,next() ⽅法才将其后输⼊的空格键、Tab 键或 Enter 键等视为分隔符或结束符2. nextLine() ⽅法的结束符只是 Enter 键。

ACM模板(Java)

ACM模板(Java)

ACM模板(Java)模板TrieHIHOCODER1014static final int N = (int)1e5+10;static final int SIGMA=(int)27;static int ch[][]=new int[N*10][SIGMA],sz;static int var[]=new int[N*10];static void insert(String x){int u=0;for(int i=0;i<x.length();i++){int c=x.charAt(i)-'a';if(ch[u][c]==0){for(int t=0;t<SIGMA;t++){ch[sz][t]=0;}ch[u][c]=sz;var[sz++]=0;}u=ch[u][c];var[u]++;}}static int search(String x){int u=0;for(int i=0;i<x.length();i++){int c=x.charAt(i)-'a';if(ch[u][c]!=0) u=ch[u][c];else return 0;}return var[u];}static void clear() {sz=1;var[0]=0;for(int i=0;i<SIGMA;i++) {ch[0][i]=0;}}KMPHIHOCODER 1015写法1static void getFail(char[] b) {int m=b.length,j=0;f[0]=f[1]=0;for(int i=1;i<m;i++) {while(j>0&&b[j]!=b[i]) j=f[j];if(b[j]==b[i]) j++;f[i+1]=j;}}static int kmp_count(char[] a,char[] b) {int n=a.length,m=b.length;int j=0,res=0;for(int i=0;i<n;i++) {while(j>0&&b[j]!=a[i]) j=f[j];if(b[j]==a[i]) j++;if(j==m) {j=0;res++;}}return res;写法2static void getFail(char[] b,int m) {int j=0;f[1]=0;for(int i=2;i<=m;i++) {while(j>0&&b[j+1]!=b[i]) j=f[j];if(b[j+1]==b[i]) j++;f[i]=j;}}static int kmp_count(char[] a,char[] b,int n,int m) { int j=0,res=0;for(int i=1;i<=n;i++) {while(j>0&&b[j+1]!=a[i]) j=f[j];if(b[j+1]==a[i]) j++;if(j==m) {j=0;res++;}}return res;}ManacherHIHOCODER1016static final int N=(int)1e6+10;static char a[]=new char[N],str[]=new char[2*N+5]; static int p[]=new int[2*N+5],len1,len2;static void Init(){len1=a.length;str[0]='(';str[1]='#';for(int i=0;i<len1;i++){str[i*2+2]=a[i];str[i*2+3]='#';}len2=len1*2+2;str[len2]=')';}static int Manacher(){for(int i=0;i<len2;i++) p[i]=0;int id=0,mx=0,ans=0;for(int i=1;i<len2;i++){if(mx>i) p[i]=Math.min(mx-i,p[2*id-i]);else p[i]=1;for(;str[i+p[i]]==str[i-p[i]];p[i]++);if(p[i]+i>mx){mx=p[i]+i;id=i;}if(p[i]-1>ans) ans=p[i]-1;}return ans;}Tire图HIHOCODER 1036static int sz;static final int N=1000005;static class Node{Node(){post = 0;for(int i = 0; i < 26; i++)next[i] = 0;end = false;int post;int next[]=new int[26];boolean end;};static Node nodes[]=new Node[N];//将str添加到trie图中static void insert(String str){int cur=0;for(int i=0;i<str.length();i++){if(nodes[cur].next[str.charAt(i)-'a'] == 0)nodes[cur].next[str.charAt(i)-'a'] = ++sz;cur = nodes[cur].next[str.charAt(i)-'a'];}nodes[cur].end = true;}//为trie图中的每个点添加它指向的后缀点位置static void addPost(){LinkedList<Integer> que = new LinkedList<Integer>();que.push(0);int cur;while(!que.isEmpty()){cur=que.pop();for(int i=0;i<26;i++){if(nodes[cur].next[i]!=0){que.push(nodes[cur].next[i]);if(cur != 0)//不是根结点,需要设置当前点的⼦节点的后缀=⽗结点的后缀经过i到达的点 nodes[nodes[cur].next[i]].post = nodes[nodes[cur].post].next[i];}else //nodes[current].next[i] == -1当前点经过i没有可达的nodes[cur].next[i] = nodes[nodes[cur].post].next[i];}}}//查找strstatic boolean search(String str){int cur = 0;for(int i=0;i<str.length();i++){if(nodes[nodes[cur].next[str.charAt(i)-'a']].end)return true;cur = nodes[cur].next[str.charAt(i)-'a'];}return false;}static void Init() {sz=0;for(int i=0;i<=1000000;i++) {nodes[i]=new Node();}}。

acmjava的输入输出

acmjava的输入输出

acmjava的输⼊输出这⾥指的java速成,只限于java语法,包括输⼊输出,运算处理,字符串和⾼精度的处理,进制之间的转换等,能解决OJ上的⼀些⾼精度题⽬。

1. 输⼊:格式为:Scanner cin = new Scanner (new BufferedInputStream(System.in));例程:import java.io.*;import java.math.*;import java.util.*;import java.text.*;publicclass Main{publicstaticvoid main(String[] args){Scanner cin = new Scanner (new BufferedInputStream(System.in));int a; double b; BigInteger c; String d;a = cin.nextInt();b = cin.nextDouble();c = cin.nextBigInteger();d = cin.ne xtLine(); // 每种类型都有相应的输⼊函数.}}2. 输出函数:System.out.print(); System.out.println(); System.out.printf();System.out.print(); // cout<< …;System.out.println(); // cout<< … <System.out.printf(); // 与C中的printf⽤法类似.例程:import java.io.*;import java.math.*;import java.util.*;import java.text.*;publicclass Main{publicstaticvoid main(String[] args){int a; double b;a = 12345;b = 1.234567;System.out.println(a + " " + b);System.out.printf("%d %10.5f\n", a, b); // 输出b为字宽为10,右对齐,保留⼩数点后5位,四舍五⼊.}}规格化的输出:函数:// 这⾥0指⼀位数字,#指除0以外的数字(如果是0,则不显⽰),四舍五⼊. DecimalFormatfd = new DecimalFormat("#.00#"); DecimalFormatgd = new DecimalFormat("0.000");System.out.println("x =" + fd.format(x));System.out.println("x =" + gd.format(x));3. 字符串处理java中字符串String是不可以修改的,要修改只能转换为字符数组.例程:import java.io.*;import java.math.*;import java.util.*;import java.text.*;publicclass Main{publicstaticvoid main(String[] args){int i;String st = "abcdefg";System.out.println(st.charAt(0)); // st.charAt(i)就相当于st[i]. char[] ch;ch = st.toCharArray(); // 字符串转换为字符数组.for(i = 0; iSystem.out.println(ch); // 输出为“bcdefgh”.if(st.startsWith("a")) // 如果字符串以'0'开头.{st = st.substring(1); // 则从第1位开始copy(开头为第0位).}}}BigInteger和BigDecimal可以说是acmer选择java的⾸要原因。

ACM模板--我的第一份ACM模板

ACM模板--我的第一份ACM模板

求逆序数int solve(int f,int l){int mid=(f+l)/2,j=0,h1=f,h2=mid+1;int sum=0;if(f==l) return 0;sum+=(solve(f,mid)+solve(mid+1,l));for(;h1<=mid&&h2<=l;){if(str[i][h1]<=str[i][h2]){tem[j++]=str[i][h1];h1++;}else {tem[j++]=str[i][h2];h2++;sum+=mid-h1+1;}}while(h1<=mid){tem[j++]=str[i][h1++];}while(h2<=l){tem[j++]=str[i][h2++];}memcpy(&str[i][f],tem,sizeof(char)*j);return sum;}经典宽搜visited[a.x][a.y]=0;while (s != e && s<=N*N && e<=N*N){c = queue[s];if (c.x == b.x && c.y == b.y) break;for (i=0;i<8;i++){c = queue[s];c.x += d[i][0];c.y += d[i][1];if (visited[c.x][c.y]==1 && c.x>=0 && c.x<l && c.y>=0 && c.y<l){visited[c.x][c.y]=0;c.step++;queue[e++]=c;}}s++;}深搜一道void DFS(int a,int b){int i,j;if(putk == k){sum++;return;}visited[b]=1;for(i=a+1;i<n;i++)for(j=0;j<n;j++)if(c[i][j]=='#' && visited[j]==0){putk++;DFS(i,j);putk--;}visited[b]=0;}滑雪DPint f(int a,int b){int tem=0;if(visited[a][b]==1) return arr[a][b];if(a-1>=0 && map[a-1][b]<map[a][b])if(tem<f(a-1,b)) tem=f(a-1,b);if(a+1<r && map[a+1][b]<map[a][b])if(tem<f(a+1,b)) tem=f(a+1,b);if(b-1>=0 && map[a][b-1]<map[a][b])if(tem<f(a,b-1)) tem=f(a,b-1);if(b+1<c && map[a][b+1]<map[a][b])if(tem<f(a,b+1)) tem=f(a,b+1); //此处切记不要把f写成arr!!visited[a][b]=1;arr[a][b]=tem+1;return arr[a][b];}最长上升子序列(二分)for(i=0;i<n;i++){left=1;right=len;while(left<=right){mid=(left+right)/2;if(b[mid]<a[i]) left=mid+1;else right=mid-1;}b[left]=a[i];f[i]=left;if(len<left) len=left;if(ans<left) ans=left;}最长上升子序列void DP(int x){int i,j=0,max=0;for(i=0;i<x;i++)if(a[i]<a[x]) h[j++]=f[i];for(i=0;i<j;i++)if(max<h[i]) max=h[i];f[x]=max+1;}01背包int main(){int i,ans,j,t;scanf("%d%d",&n,&m);for(i=0;i<n;i++)scanf("%d%d",&a[i].w,&a[i].d);for(i=0;i<=m;i++)f[0][i]=0;for(i=1,t=1;i<=n;i++,t=1-t)for(j=0;j<=m;j++){f[t][j]=f[1-t][j];if(j>=a[i-1].w && f[1-t][j-a[i-1].w]+a[i-1].d>f[t][j])f[t][j]=f[1-t][j-a[i-1].w]+a[i-1].d;}ans=f[1-t][m];printf("%d\n",ans);}最长公共子序列•若给定序列X={x1,x2,…,x m},则另一序列Z={z1,z2,…,z k},是X的子序列是指存在一个严格递增下标序列{i1,i2,…,i k}使得对于所有j=1,2,…,k有:z j=x ij。

ACM题目分类(参考模板)

ACM题目分类(参考模板)

-----------------------------最优化问题-----------------------------------------------------------常规动态规划SOJ1162 I-KeyboardSOJ1685 ChopsticksSOJ1679 GangstersSOJ2096 Maximum SubmatrixSOJ2111 littleken bgSOJ2142 Cow ExhibitionSOJ2505 The County FairSOJ2818 QQ音速SOJ2469 Exploring PyramidsSOJ1833 Base NumbersSOJ2009 Zeros and OnesSOJ2032 The Lost HouseSOJ2113 数字游戏SOJ2289 A decorative fenceSOJ2494 ApplelandSOJ2440 The days in fzkSOJ2494 ApplelandSOJ2515 Ski LiftSOJ2718 BookshelfSOJ2722 Treats for the CowsSOJ2726 Deck of CardsSOJ2729 Space ElevatorSOJ2730 Lazy CowsSOJ2713 Cut the SequenceSOJ2768 BombSOJ2779 Find the max (I) (最大M子段和问题)SOJ2796 Letter DeletionSOJ2800 三角形SOJ2804 Longest Ordered Subsequence (II)SOJ2848 River Hopscotch(二分)SOJ2849 Cow Roller CoasterSOJ2886 Cow WalkSOJ2896 AlphacodeSOJ2939 bailey's troubleSOJ2994 RSISOJ3037 Painting the ballsSOJ3072 ComputersSOJ3078 windy's "K-Monotonic"SOJ3084 windy's cake IVSOJ3104 Game(注意大数运算,高精度)SOJ3110 k Cover of LineSOJ3111 k Median of LineSOJ3123 Telephone WireSOJ3142 Unfriendly Multi PermutationSOJ3213 PebblesSOJ3219 Cover UpSOJ3263 FunctionSOJ3264 Evil GameSOJ3339 graze2SOJ3341 SkiSOJ3352 The Baric BovineSOJ3503 Banana BoxesSOJ3633 Matches's GameSOJ3636 理想的正方形SOJ3711 Mountain RoadSOJ3723 Robotic Invasionnankai1134 Relation Orderingsrm150--div1--500----------------背包问题SOJ2222 Health PowerSOJ2749 The Fewest CoinsSOJ2785 Binary PartitionsSOJ2930 积木城堡SOJ3172 FishermanSOJ3300 Stockholm CoinsSOJ3360 Buying HaySOJ3531 Number Pyramids----------------状态DPSOJ2089 lykooSOJ2768 BombSOJ2819 AderSOJ2842 The TSP problemSOJ3025 Artillery(状态DP)SOJ3088 windy's cake VIIISOJ3183 Fgjlwj's boxesSOJ3259 Counting numbersSOJ3262 Square Fields(二分+状态DP) SOJ3371 Mixed Up CowsSOJ3631 Shopping Offers----------------树状DPSOJ 1870 Rebuilding RoadsSOJ 2136 Apple(树形依赖背包n*C算法) SOJ 2514 Milk Team SelectSOJ 2199 Apple TreeSOJ 3295 Treeland ExhibitionSOJ 3635 World Cup 2010hdoj1561 The more, The BetterPKU1655 Balancing ActPKU3107 GodfatherPKU3345 Bribing FIPAPKU2378 Tree CuttingPKU3140 Contestants DivisionPKU3659 Cell Phone Network---------------配合数据结构的优化DPSOJ 2702 AlannaSOJ 2978 TasksSOJ 3234 Finding SeatsSOJ 3540 股票交易-------------- 斜率优化SOJ 3710 特别行动队SOJ 3734 搬家SOJ 3736 Lawrence of Arabia---------------四边形不等式SOJ 1702 Cutting SticksSOJ 2775 Breaking Strings--------------- 最优化之排序(思考两个元素之间的先后关系,以此得出一个二元比较关系,并验证此关系可传递,反对称,进而排序)SOJ2509 The Milk QueueSOJ2547 cardsSOJ2850 Protecting the FlowersSOJ2957 Setting ProblemsSOJ3167 ComputerSOJ3331 Cards(2547加强版)SOJ3327 Dahema's Computer(通过此题学会排序)-----------------最优化之必要条件枚举(思考最优解所具有的性质,得出最优解的一个强必要条件,在此基础上枚举)SOJ3317 FGJ's PlaneSOJ3429 Food portion sizes--------------------------------贪心---------------------------------------SOJ1078 BlueEyes' ScheduleSOJ1203 Pass-MurailleSOJ1673 Gone FishingSOJ2574 pieSOJ2645 Buy One Get One FreeSOJ2701 In a CycleSOJ2876 Antimonotonicity(经典模型 O(n)算法)SOJ3343 Tower--------------------------------搜索---------------------------------------SOJ1106 DWeepSOJ1626 squareSOJ2061 8 puzzleSOJ2485 SudokuSOJ1045 SticksSOJ2736 FliptileSOJ2771 Collecting StonesSOJ2715 Maze BreakSOJ2518 Magic Cow ShoesSOJ2829 binary strings(双向BFS)SOJ3005 Dropping the stonesSOJ3136 scu07t01的迷宫(BFS预处理然后枚举交汇点)SOJ3330 Windy's Matrix(BFS)--------------------------------DFA-------------------------------------------------------状态矩阵SOJ1826 Number SequenceSOJ1936 FirepersonsSOJ2552 Number of TilingsSOJ2919 Matrix Power Series (学习矩阵的快速乘法从此开始)SOJ2920 Magic BeanSOJ3021 Quad TilingSOJ3046 Odd Loving BakersSOJ3176 E-stringSOJ3246 Tiling a Grid With DominoesSOJ3323 K-Satisfied NumbersSOJ3337 Wqb's Word----------------DFA+DPSOJ1112 Repeatless Numbers(DFA+二分)SOJ2913 Number SubstringSOJ2826 Apocalypse SomedaySOJ3128 windy和水星 -- 水星数学家 1SOJ3182 Windy numbers---------------------------------图论-----------------------------------------------------------最短路SOJ1697 Cashier EmploymentSOJ2325 Word TransformationSOJ2427 Daizi's path systemSOJ2468 CatcusSOJ2751 Wormholes(SPFA判断负圈回路的存在性)SOJ2932 道路SOJ3160 Clear And Present DangerSOJ3335 Windy's Route(最短路径的分层图思想)SOJ3346 Best Spot(N^3放心的写)SOJ3423 Revamping Trails---------------------查分约束SOJ1687 Intervals---------------------最小生成树SOJ1169 NetworkingSOJ2198 HighwaysSOJ3366 Watering HoleSOJ3427 Dark roads---------------------强连通分支SOJ2832 Mars city---------------------2-SATSOJ3535 Colorful DecorationHDU3062 Party---------------------拓扑排序SOJ1075 BlueEyes and Apples (II)---------------------无向连通图上的割点和割边问题SOJ1935 ElectricityWHU145 Railway---------------------二分图的匹配------------------最大匹配SOJ1183 Girls and BoysSOJ1186 CoursesSOJ2035 The Tiling ProblemSOJ2077 Machine ScheduleSOJ2160 Optimal MilkingSOJ2342 Rectangles(Beloved Sons 模型)SOJ2472 Guardian of DecencySOJ2681 平方数 2SOJ2737 AsteroidsSOJ2764 Link-up GameSOJ2806 LED DisplaySOJ2958 Weird FenceSOJ3043 Minimum CostSOJ3038 Beloved Sons(简单贪心一下)SOJ3453 Stock ChartsZOJ3265 Strange Game---------------最佳匹配SOJ1981 Going HomeWHU1451 Special Fish---------------------最近公共祖先问题SOJ1187 Closest Common AncestorsSOJ1677 How far awaySOJ3023 NetworkSOJ3098 Bond---------------------其他SOJ3013 treeSOJ3056 Average distance(树上的DFS)---------------------------------网络流----------------------------------------------------------最大流POJ 1273 Drainage DitchesPOJ 1274 The Perfect Stall (二分图匹配)POJ 1698 Alice's ChancePOJ 1459 Power NetworkPOJ 2112 Optimal Milking (二分)POJ 2455 Secret Milking Machine (二分)POJ 3189 Steady Cow Assignment (枚举)POJ 1637 Sightseeing tour (混合图欧拉回路)POJ 3498 March of the Penguins (枚举汇点)POJ 1087 A Plug for UNIXPOJ 1149 Pigs (构图题)ZOJ 2760 How Many Shortest Path (边不相交最短路的条数)POJ 2391 Ombrophobic Bovines (必须拆点,否则有BUG)WHU 1124 Football Coach (构图题)SGU 326 Perspective (构图题,类似于 WHU 1124)UVa 563 CrimewaveUVa 820 Internet BandwidthPOJ 3281 Dining (构图题)POJ 3436 ACM Computer FactoryPOJ 2289 Jamie's Contact Groups (二分)SGU 438 The Glorious Karlutka River =) (按时间拆点)SGU 242 Student's Morning (输出一组解)SGU 185 Two shortest (Dijkstra 预处理,两次增广,必须用邻接阵实现,否则 MLE) HOJ 2816 Power LinePOJ 2699 The Maximum Number of Strong Kings (枚举+构图)ZOJ 2332 GemsJOJ 2453 Candy (构图题)SOJ 2414 Leapin' LizardsSOJ 2835 Pick Up PointsSOJ 3312 Stockholm KnightsSOJ 3353 Total Flow--------------------最小割SOJ2662 PlaygroundSOJ3106 Dual Core CPUSOJ3109 Space flightSOJ3107 SelectSOJ3185 Black and whiteSOJ3254 Rain and FgjSOJ3134 windy和水星 -- 水星交通HOJ 2634 How to earn moreZOJ 2071 Technology Trader (找割边)HNU 10940 CoconutsZOJ 2532 Internship (找关键割边)POJ 1815 Friendship (字典序最小的点割集)POJ 3204 Ikki's Story I - Road Reconstruction (找关键割边)POJ 3308 ParatroopersPOJ 3084 Panic RoomPOJ 3469 Dual Core CPUZOJ 2587 Unique Attack (最小割的唯一性判定)POJ 2125 Destroying The Graph (找割边)ZOJ 2539 Energy MinimizationZOJ 2930 The Worst ScheduleTJU 2944 Mussy Paper (最大权闭合子图)POJ 1966 Cable TV Network (无向图点连通度)HDU 1565 方格取数(1) (最大点权独立集)HDU 1569 方格取数(2) (最大点权独立集)HDU 3046 Pleasant sheep and big big wolfPOJ 2987 Firing (最大权闭合子图)SPOJ 839 Optimal Marks (将异或操作转化为对每一位求最小割)HOJ 2811 Earthquake Damage (最小点割集)2008 Beijing Regional Contest Problem A Destroying the bus stations ( BFS 预处理 )(http://acmicpc-live-archive.uva.es/nuevoportal/data/problem.php?p=4322) ZOJ 2676 Network Wars (参数搜索)POJ 3155 Hard Life (参数搜索)ZOJ 3241 Being a Hero-----------------有上下界ZOJ 2314 Reactor Cooling (无源汇可行流)POJ 2396 Budget (有源汇可行流)SGU 176 Flow Construction (有源汇最小流)ZOJ 3229 Shoot the Bullet (有源汇最大流)HDU 3157 Crazy Circuits (有源汇最小流)-----------------最小费用流HOJ 2715 Matrix3HOJ 2739 The Chinese Postman ProblemPOJ 2175 Evacuation Plan (消一次负圈)POJ 3422 Kaka's Matrix Travels (与 Matrix3 类似)POJ 2516 Minimum Cost (按物品种类多次建图)POJ 2195 Going HomePOJ 3762 The Bonus Salary!BUAA 1032 Destroying a PaintingPOJ 2400 Supervisor, Supervisee (输出所有最小权匹配)POJ 3680 IntervalsHOJ 2543 Stone IVPOJ 2135 Farm TourSOJ 3186 SegmentsSOJ 2927 终极情报网SOJ 3634 星际竞速HDU 3376 Matrix Again-----------------------------------数据结构--------------------------------------------------------------------基础数据结构----------------------栈SOJ2511 MooooSOJ3085 windy's cake V(经典栈与单调性的结合)SOJ3279 hm 与 zx 的故事系列2SOJ3329 Maximum Submatrix II(转化为上面两题的模型)---------------------双端队列SOJ2978 TasksSOJ3139 Sliding Window(双端队列最经典的应用)SOJ3636 理想的正方形-------------------- --------------高级数据结构---------------------线段树SOJ1862 Choice PearsSOJ2057 The manager's worrySOJ2249 Mayor's postersSOJ2309 In the Army NowSOJ2436 Picture puzzle gameSOJ2556 Find the PermutationSOJ2562 The End of CorruptionSOJ2719 Corral the Cows(线段树+二分)SOJ2740 Balanced LineupSOJ2745 零序列SOJ2776 Matrix SearchingSOJ2808 Thermal Death of the UniverseSOJ2822 Buy TicketsSOJ2937 TetrisSOJ2938 Apple Tree(先DFS获得欧拉序列)SOJ2965 capitally playersSOJ2968 Matrix(二维线段树)SOJ3019 Count ColorSOJ3022 Difference Is Beautiful( RMQ+二分经典模型)SOJ3086 windy's cake VI(二维线段树)SOJ3099 A Simple Problem with IntegersSOJ3248 MousetrapSOJ3321 Windy's Sequence IISOJ3370 Light SwitchingSOJ3640 Special Subsequence---------------------树状数组SOJ2309 In the Army Now---------------------归并排序思想SOJ2906 Ultra-QuickSortSOJ2431 Cows distribute food(利用归并排序求逆序数:nlogn) SOJ2497 Number sequenceSOJ2559 What is the Rank?SOJ2728 MooFestSOJ3009 Stones for AmySOJ3010 K-th NumberSOJ3147 K-th number---------------------并查集SOJ1824 The SuspectsSOJ1953 keySOJ2245 Ubiquitous ReligionsSOJ2389 Journey to TibetSOJ2438 PetSOJ2490 Math teacher's testPOJ2832 How many pairs?POJ2821 Auto-Calculation MachineSOJ2979 食物链SOJ3282 Kingdom of HeavenSOJ3417 Skyscrapers------------------------块状链表SOJ3032 Big StringSOJ3035 反转序列----------------------------------- 字符串---------------------后缀数组SOJ1948 sekretarkaSOJ3045 Long Long MessageSOJ3075 回文子串SOJ3296 Windy's S---------------------KMPSOJ2652 OulipoSOJ2307 String MatchingSOJ3014 Seek the Name, Seek the FameSOJ3596 Article Decryption--------------------trie树SOJ3076 相同字符串SOJ3336 DiarySOJ3596 Article Decryption---------------------------------组合数学及数论-----------------------------SOJ1839 Relatives(Euler函数)SOJ1942 FotoSOJ2714 Mountains (II)SOJ2668 C(n,k)SOJ2666 分解 n!SOJ2106 GCD & LCM InverseSOJ2498 Count primeSOJ2238 Let it Bead(置换群-polya定理的应用)SOJ2924 完美交换(置换群)SOJ2638 Cow Sorting(置换群)-------------费马小定理SOJ 3578 H1N1's Problem--------------------------容斥原理SOJ3191 Free squareSOJ3082 windy's cake IISOJ3502 The Almost Lucky NumbersSOJ3547 Coprime----------------------------------博弈论------------------------------------SOJ1128 控制棋SOJ1866 Games(诡异的博弈)SOJ2197 A Funny GameSOJ2188 A multiplication gameSOJ2403 Black and white chessSOJ2477 Simple GameSOJ2687 草稿纸 2SOJ2688 草稿纸 3SOJ2836 Pick Up Points IISOJ2845 JangeSOJ2922 A New Tetris GameSOJ2993 NimSOJ3066 JohnSOJ3132 windy和水星 -- 水星游戏 1SOJ3133 windy和水星 -- 水星游戏 2SOJ3174 Good gameSOJ3307 Stockholm GameSOJ3446 Nim or not NimSOJ3461 Nim-kSOJ3463 Ordered NimSOJ3468 Flip CoinsSOJ3548 game如不慎侵犯了你的权益,请联系告知!SOJ3584 Baihacker and Oml-----------------------------------计算几何---------------------------------SOJ1138 WallSOJ1102 Picnic(本资料素材和资料部分来自网络,仅供参考。

java之acm模板

java之acm模板

java之acm模板//import java.util.Scanner;//相当于输⼊输出头⽂件import java.util.*;//啥都有头⽂件//import java.math.BigInteger;//⼤数类import java.math.BigDecimal;//⼤浮点数import java.math.*;//关于数学的头⽂件public class Main {public static void main(String[] args) {BigInteger[] sum=new BigInteger[105];//开⼀个数组Scanner cin = new Scanner(System.in);//必须要写这句话(输⼊)int t = cin.nextInt();//输⼊整数T nextInt() 下⼀个int型数据// while(cin.hasNext()) {//循环输⼊,hasNext()// int n = cin.nextInt();// }while (t--!=0) {//java⾥不能直接写while(t--),必须是只有真假的表达式BigInteger a = cin.nextBigInteger();//输⼊下⼀个⼤数BigInteger b = cin.nextBigInteger();//输⼊下⼀个⼤数BigInteger c;c = a.add(b);//c=a+bc = a.subtract(b);//c=a-bc = a.multiply(b);//c=a*bc = a.divide(b);//c=a/b(整数除法)c = a.remainder(b);//c=a%bc = a.mod(b);//c=a%b(结果为正数)c = BigInteger.ZERO;//c=0c = BigInteger.ONE;//c=1c = BigInteger.TEN;//c=10 java⼤数中只有0,1,10c = BigInteger.valueOf(7);//c=7int n = 7;c = BigInteger.valueOf(n);//c=nc = a.pow(n);//幂运算 c=pow(a,n)c = a.gcd(b);//最⼤公约数 c=gcd(a,b)c = a.abs();//c = a.max(b);//c=max(a,b)c = a.min(b);//c=min(a,b)n = pareTo(b);//a<b n=-1;a=b n=0;a>b n=1a.equals(b);//a==ba.isProbablePrime(2);//判断素数,有⼀定⼏率错误,最好⼿写System.out.println(c);//输出c并换⾏System.out.print(c);//输出cSystem.out.println(a+" "+b);//输出a空格bBigDecimal d = cin.nextBigDecimal();//输⼊下⼀个⾼精度浮点数BigDecimal e = cin.nextBigDecimal();//输⼊下⼀个⾼精度浮点数BigDecimal f = d.add(e);//f=d+e//...其他和⼤数类似f = d.setScale(2);//保留2位⼩数,默认四舍五⼊f = d.setScale(2,BigDecimal.ROUND_DOWN);//保留2位⼩数,向下取整f = d.setScale(2,BigDecimal.ROUND_UP);//保留2位⼩数,向上取整f = d.setScale(2,BigDecimal.ROUND_HALF_DOWN);//保留2位⼩数,四舍五⼊,正好.5舍去f = d.setScale(2,BigDecimal.ROUND_HALF_UP);//保留2位⼩数,四舍五⼊,正好.5进位}}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

2/25
28 return new T(key, val, t.p, t.left, t.right); 29 } 30 T remove(T t, int key) { 31 32 if (t == null) return null; if (key < t.key) return t.change(remove(t.left, key), t.right);
University of Tokyo
2 13 int res = 0; for (int i = t; i > 0; i -= i & -i) { res += vs[i]; } return res; } //[0,i] k int get(int k) { i
1/25
1
1 import static ng.Math.*; 2 import static java.util.Arrays.*; 3 import java.io.*; 4 import java.util.*; 5 6 public class Main { 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 } } static boolean LOCAL = System.getSecurityManager() == null; Scanner sc = new Scanner(System.in); void run() { } void debug(Object...os) { System.err.println(deepToString(os)); } public static void main(String[] args) { if (LOCAL) { try { System.setIn(new FileInputStream("in.txt")); } catch (Throwable e) { LOCAL = false; } } new Main().run();
University of Tokyo 2.3 1 class Intervals { 2 TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>(); 3 Intervals() { 4 5 6 7 8 9 10 11 12 13 14 15 16 } 2.4 Treap 1 class T { 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 final int key, val; final double p; final T left, right; T(int key, int val, double p, T left, T right) { this.key = key; this.val = val; this.p = p; this.left = left; this.right = right; } T change(T left, T right) { return new T(key, val, p, left, right); } T normal() { if (left != null && left.p < p && (right == null || left.p < right.p)) { return left.change(left.left, change(left.right, right)); } else if (right != null && right.p < p) { return right.change(change(left, right.left), right.right); } return this; } map.put(Integer.MIN_VALUE, -1); map.put(Integer.MAX_VALUE, -1); } void paint(int s, int t, int c) { int p = get(t); map.subMap(s, t).clear(); map.put(s, c); map.put(t, p); } int get(int k) { return map.floorEntry(k).getValue(); }
26 return p; 27 } 28 } 2.2 RMQ 1 class RMQ { 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 } int[] vs; int[][] min; RMQ(int[] vs) { int n = vs.length, m = log2(n) + 1; this.vs = vs; min = new int[m][n]; for (int i = 0; i < n; i++) min[0][i] = i; for (int i = 1, k = 1; i < m; i++, k <<= 1) { for (int j = 0; j + k < n; j++) { min[i][j] = vs[min[i - 1][j]] <= vs[min[i - 1][j + k]] ? min[i - 1][j] : min[i - 1][j + k]; } } } // int query(int from, int to) { int k = log2(to - from); return vs[min[k][from]] <= vs[min[k][to - (1 << k)]] ? min[k][from] : min[k][to - (1 << k)]; } int log2(int b) { return 31 - Integer.numberOfLeadingZeros(b); }
7 return n; 8 } 9 void dfs(V v) { 10 11 v.visit = true; for (V u : v.fs) if (!u.visit) dfs(u);
12 us[--n] = v; 13 } 14 void dfsrev(V v, int k) { 3.1.7 Tutte Tutte xvu x 3.2 v[i] v[j] ⇒i<j num[v] v v : r u ⇔r low[u] 2 u num[u] 3.4 DFS low 1 V[] topologicalSort(V[] vs) { 2 3 4 5 n = vs.length; us = new V[n]; for (V v : vs) { if (v.state == 0 && !dfs(v)) return null; num V ×V G tvu = xvu , tuv = −xvu Tutte G
2
2.1 BITBinaryIndexedTree 1 class BIT { 2 int[] vs; 3 BIT(int n) { 4 5 6 7 8 9 10 11 12 vs = new int[n + 1]; } void add(int k, int a) { for (int i = k + 1; i < vs.length; i += i & -i) { vs[i] += a; } } int sum(int s, int t) { if (s > 0) return sum(0, t) - sut, int key, int val) {
University of Tokyo 21 22 23 24 } 25 } } //... t -= t & -t;
3 6 }
3/25
7 return us; 8 } 9 boolean dfs(V v) { 10 v.state = 1; 11 for (V u : v) { 12 13 14 15 16 17 }
2 25 26 27 if (t == null) return new T(key, val, random(), null, null); if (key < t.key) return t.change(put(t.left, key, val), t.right).normal(); if (key > t.key) return t.change(t.left, put(t.right, key, val)).normal();
+ δG (X )
if (u.state == 1 || u.state == 0 && !dfs(u)) return false; } us[--n] = v; v.state = 2; return true;
3
3.1 3.1.1 V, 3.1.2 MaxFlow-MinCut s-t= G 3.1.3 | | |≤| |+| | | X ⊆ V (G) 3.1.4 G 3.1.5 Kn i di (n − 2)! (d1 − 1)!(d2 − 1)! . . . (dn − 1)! 3.1.6 Kasteleyn ( -1 ) (G −G ) G |=| ⇔ V (G) \ X |( |=V |+| | G ) s-tGf s X E, F V −E+F =2
14 15 16 17 18 19 20 21 22 23 24 25
int p = Integer.highestOneBit(vs.length - 1); for (int q = p; q > 0; q >>= 1, p |= q) { if (p >= vs.length || k < vs[p]) p ^= q; else k -= vs[p]; }
相关文档
最新文档