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.括号化问题。

  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]; }
相关文档
最新文档