搜档网
当前位置:搜档网 › ACM入门训练指南

ACM入门训练指南

ACM入门训练指南
ACM入门训练指南

ACM入门训练指南

目标读者:

想要在ACM/ICPC里进行发展,并通过SDUTOJ进行训练的初学者。

使用语言:

只要会一门程序设计语言,就可以进行ACM训练了。通过训练,可以更好地掌握语言使用能力、程序和算法设计能力。

一般通用语言如C、C++和JAVA都可以,它们有各自的优势和缺点:

1.C语言设计算法效率比较高,但输入输出的格式控制比较麻烦,而ACM 对程序进行评测时对输入输出的格式要求比较高,使用C务必要熟练掌握输入输出方法。

2.C++封装了输入输出流,方便输入输出操作,减少出错的可能性;C++提供了非常强大的标准模版库(STL),使得很多在C上实现起来比较麻烦的代码,在C++上却非常方便。

3.JAVA在大型工程和安全方面有比较独特的优势,但在ACM里面却不是一种优秀的语言,因为JAVA的执行效率要比C、C++慢很多,而ACM的题目都对程序运行时间有限制,如果题目限时比较紧的话,就不适合用JAVA,然而JAVA却提供了很方便的高精度运算(大整数运算)。

建议刚学完C就用纯C来训练,在训练过程中可以学习C++,有时间再把STL 好好学学。

输入输出:

初次接触ACM训练时经常会遇到的问题,就是输入和输出问题。如果对语言的输入输出问题不是很熟悉的话,一定要先重点研究一下,特别在输入和输出时不能有冗余信息,因为学习语言时可能习惯了使用提示信息来提高程序的交互性,但ACM不需要任何交互性。不严格按照题目要求进行输入输出的程序是无法通过系统测试的。

在线评测系统:

在线评测系统,英文叫Online Judge(简称OJ),是开放的程序自动评判系统。只要能上网,注册并登录系统后,就可以选择题目,编写程序,提交程序代码,然后由系统自动进行编译和执行,并通过系统预设测试数据来检验程序代码的正确性。通过使用OJ训练,可以提高编程和算法设计能力,随着训练的深入,可以参加在评测系统上举行的ACM-ICPC程序设计竞赛。

很多学校都有自己的在线评测系统,里面提供了很多题目给平时学习训练用。SDUTOJ是我们学校的在线评测系统。需要先在上面进行注册,注册后就可以进行题目的训练了。

点击主页上的“练习”,就可以看到里面的题库,可以选任何一个题来做,里面的题目不是由易到难进行排列,而初学者要选择比较简单的题目来做。一般来讲,每道题目都有正确率Ratio(AC/Submit)——正确次数/提交总次数,那些正确率比较高并且提交次数比较多的相对就会比较简单。

一旦确定了做某道题,在读懂题意以后,就可以进行构思和编码了,编码完成后进行程序的调试。一般不直接在OJ的提交页面输入代码,而是先利用VC6.0等开发环境进行程序的编译、调试和运行。因为即使编译成功的程序运行也不一定就正确,要用题目提供的样例输入数据(示例输入Sample Input)进行测试,如果结果和样例输出数据(示例输出Sample Output)不一致,就要对代码进行修改,直到能通过所有测试数据。

初学者经常会碰到这样的问题:我的程序运行后对示例输入(Sample Input)数据得到了对应的示例输出(Sample Output)呀,为什么提交的时候仍然不正确呢?这是因为OJ系统中关于这道题目的测试数据远远不止这些,它还有许多你看不到的测试数据,你的程序必须要能通过它所有的数据,才算是正确的(Accepted)。如果有能力,需要根据题意自己设计一些测试数据来测试程序,以便保证提交的正确率。

下面挑出最简单的一个题(SDUTOJ1010)进行讲解:

题目名称下面的“Time Limit:1000MS Memory Limit:60000K”是题目的运行时间和使用内存限制。

这是一个求两数之和的题目,输入用空格分开的两个数a b,输出a+b的结果。编写代码时需要注意的是,本题的输入数据不是只有一对数据,而是多对数据,每对数据占一行。因为没有指出共有多少对输入数据,于是我们可以编写如下代码:

//C语言

#include

int main() //把main函数定义成int类型

{

int a,b;

while(scanf("%d %d",&a, &b) != EOF) // 输入文件结束时,scanf函数返回值为EOF printf("%d\n",a+b); // 直到没有数据输入则退出while循环

return 0;

}

//或者C++语言

#include

using namespace std;

int main()

{

int a,b;

while(cin >> a >> b)

cout << a+b << endl;

return 0;

}

在VC等环境下调试好程序后,在题目的下面有一个“提交”按钮,点击出现提交界面,可以把调试好的代码复制上去,注意选择的题号和语言(C语言选GCC,C++选G++)。如果没有登录则需要输入自己的用户名和密码后才可以进行提交,点击“提交”:

提交后会出现题目状态列表(Problems Status List)。

完成后会根据评测结果返回提示信息,如返回结果是Accepted,表示程序正确。

并不是所有提交上去的代码都是返回Accepted,一般而言,系统返回的信息有以下几种情况:

1.等待Waiting:评测系统忙,等待系统评测。

2.正确 (AC) Accepted:程序得到了正确的结果,意味着你正确完成了题目。

3.输出格式错(PE) Presentation Error:虽然程序的结果是正确的,但是输出结果的格式与题目要求的不符,一般是由于在某些位置多输出或少输出了空

格或空行。

4.答案错误(WR) Wrong Answer:程序运行完毕,但没有输出正确的结果。

5.运行时错误(RE) Runtime Error:在程序的执行过程中,出现了堆栈溢出、访问无效内存单元、数组越界、计算中除以零等导致异常结束的情况。

6.超出时间限制(TLE) Time Limit Exceeded:程序没有在限定时间内执行完。

7.超过内存限制(MLE) Memory Limit Exceeded:程序所使用的内存空间超过了题目的限定。

8.编译错误(CE) Compile Error:程序有语法错误,没有通过编译,请仔细检查。

9.超过输出限制(OLE) Output Limit:程序产生了过多的输出信息,可能是由于死循环造成的。

除了Accepted信息外,其他信息都说明你的程序有问题,还要进行修改然后提交,直到正确。

需要注意的问题:

OJ一般只支持标准输入输出,提交的程序不允许操作文件,你的程序不能输出任何多余信息,包括提示信息,如对上面1010号题目的程序,可能会有些人这样写:

#include

int main()

{

int a,b;

while(1)

{

printf("请输入a和b:"); //此行是多余输出,题目没有要求,不允许出现if(scanf("%d %d",&a, &b) == EOF)

return 0;

printf("%d\n",a+b);

}

return 0;

}

每个题目的测试数据测试完毕后,就会以一个标记结束输入,向1010是文件结束,有些程序是特定的数据作为输入的结束,做题时一定要看清输入数据要求。

训练过程建议:

除了在SDUTOJ里训练,还可以到其他比较出名的OJ里练习,如北大、杭电等,在论坛首页的友情链接里有这些OJ的链接。

多做题,多看书,不浮躁,不气馁,不懂要问,程序设计水平一定会提高的。

初学者可以先训练必须要掌握的知识和一些入门题,仅列举SDUTOJ中的题目:

1.输入输出练习题目:1000(英文)、1010-1017(英文)、1276-1279(中文);

2.学习C语言过程中,C语言实验题目:1110-1123,1151-1208;

3.刚学完一门语言,未学算法和数据结构的同学,可以做的简单题目:1044-1109。

ACM训练题集一

poj1035:拼写检查 时间限制: 2000毫秒内存限制: 65536K 提交总数: 11190 : 4140 说明 作为一个新的拼写检查程序的开发团队成员,你写的模块,将检查使用一切形式的所有已知的正确的话字典的 话的正确性。如果这个词在字典中缺席那么它可以取代正确的话(从字典)可以取得下列操作之一: 从单词的一个字母删去 ;在任意一个字母的单词一个字母 取代,插入一个?任意字母到单词 ,你的任务是编写程序,会发现每一个给定的单词从字典中所有可能的替代。 输入 输入文件的第一部分包含从字典中的所有单词。每个字中占有它自己的行。完成这部分是由一个单独的行上的单字符'#' 。所有的字是不同的。将有10000字的字典。 文件的下一部分,包含了所有的单词进行检查。每个字中占有它自己的行。这部分也完成了由一个单独的行上的单字符'#' 。将有最多50个字进行检查。 输入文件中的所有单词(从字典和被检查的词字)只包括小字母字符,每一个包含15个字符最多。 输出 写入到输出文件中完全检查它们在输入文件的第二部分中出现的顺序每个字一行。如果这个词是正确的(即它在字典中存在)写留言:“是正确的“,如果这个词是不正确的,那么先写这两个字,然后写字符。”:“(冒号),并在一个单独的空间写了所有可能的替代品,用空格隔开这些替代应在书面的顺序。其在字典中(在输入文件的第一部分)。出现,如果有这个字没有替换,然后换行,应立即按照冒号。 样例输入 我是有我更多的比赛,我太iF奖#我知道米的较量HAV OO或我的网络连接MRE#

输出范例 我是正确的认识到:奖米:我的我的比赛是正确的甲肝:已经有OO:太:我是正确的FI:我MRE:更多的我 poj3080:蓝色牛仔裤 时间限制: 1000毫秒内存限制: 65536K 提交总数: 6173 接受日期: 2560 说明 基因地理工程是IBM与国家地理学会,是分析,从成千上万的贡献者地图地球是如何填充DNA的研究伙伴关系,作为IBM的研究人员,你一直负责编写一个程序,会发现共性之间个人调查资料,以确定新的遗传标记,可与相关的DNA 片段。DNA碱基序列是指出在它们在分子中发现的顺序列出的氮基地。有四种碱基:腺嘌呤(A),胸腺嘧啶(T),鸟嘌呤(G),胞嘧啶(C)。一个6碱基的DNA序列可以作为TAGACC代表。鉴于一组DNA碱基序列,确定在所有序列中出现的最长的系列基地。 输入 输入到这个问题,将开始与行包含一个单一的整数n表示数据集的数目。每个数据集由以下几部分组成组成: ?一个正整数m(2 <= M <= 10)的碱基序列,在此数据集。 ?m行每片含60个碱基组成的单一碱基序列。 输出 对于每一个输入数据集,输出基地序列的最长共同所有的碱基序列。如果最长的公共子序列的长度小于3基地,显示字符串“没有显着的共性”。如果存在多个子序列相同的长度最长,只输出序列的按字母顺序排列第一。

ACM竞赛试题集锦

取石子游戏 Time Limit:1S Memory Limit:1000K Total Submit:505 Accepted:90 Description 有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。 Input 输入包含若干行,表示若干种石子的初始情况,其中每一行包含两个非负整数a和b,表示两堆石子的数目,a和b都不大于1,000,000,000。 Output 输出对应也有若干行,每行包含一个数字1或0,如果最后你是胜者,则为1,反之,则为0。 Sample Input

2 1 8 4 4 7 Sample Output 1 跳蚤 Time Limit:1S Memory Limit:1000K Total Submit:198 Accepted:44 Description Z城市居住着很多只跳蚤。在Z城市周六生活频道有一个娱乐节目。一只跳蚤将被请上一个高空钢丝的正中央。钢丝很长,可以看作是无限长。节目主持人会给该跳蚤发一张卡片。卡片上写有N+1个自然数。其中最后一个是M,而前N个数都不超过M,卡片上允许

有相同的数字。跳蚤每次可以从卡片上任意选择一个自然数S,然后向左,或向右跳S个单位长度。而他最终的任务是跳到距离他左边一个单位长度的地方,并捡起位于那里的礼物。 比如当N=2,M=18时,持有卡片(10, 15, 18)的跳蚤,就可以完成任务:他可以先向左跳10个单位长度,然后再连向左跳3次,每次15个单位长度,最后再向右连跳3次,每次18个单位长度。而持有卡片(12, 15, 18)的跳蚤,则怎么也不可能跳到距他左边一个单位长度的地方。 当确定N和M后,显然一共有M^N张不同的卡片。现在的问题是,在这所有的卡片中,有多少张可以完成任务。 Input 两个整数N和M(N <= 15 , M <= 100000000)。 Output 可以完成任务的卡片数。 Sample Input

ACM练习题

ACM contests https://www.sodocs.net/doc/b615495354.html,

中庸之道(一) Time Limit: 1000 ms Memory Limit: 65535 kB Solved: 306 Tried: 1491 Description 读入三个整数a、b、c,找出中间数并输出。若有两个数相同,最大数作为中间数。Input 有多组测试数据。输入的第一行是整数T(0 int main() { int a,b,c,i,T; scanf("%d",&T); for(i=0;i

} return 0; } 或者 #include int main() { int a,b,c,T; scanf("%d",&T); while(T--) { //读入并处理当前组数据 } return 0; } 中庸之道(二) Time Limit: 1000 ms Memory Limit: 65535 kB Solved: 191 Tried: 629 Description 读入三个整数a、b、c,找出中间数并输出。若有两个数相同,最大数作为中间数。Input 有多组测试数据。每一组测试数据只有一行,分别为整数a、b和c,相邻两数之间有一个空格。该行没有其它多余的符号。如果一行三个数字均为0,表示输入结果,该行不需要处理。-2^31

ACM经典算法及配套练习题

POJ上的一些水题(可用来练手和增加自信) (poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,p oj2255,poj3094) 初期: 一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. (4)递推. (5)构造法.(poj3295) (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996) 二.图算法: (1)图的深度优先遍历和广度优先遍历. (2)最短路径算法(dijkstra,bellman-ford,floyd,heap+dijkstra) (poj1860,poj3259,poj1062,poj2253,poj1125,poj2240) (3)最小生成树算法(prim,kruskal) (poj1789,poj2485,poj1258,poj3026) (4)拓扑排序(poj1094) (5)二分图的最大匹配(匈牙利算法) (poj3041,poj3020) (6)最大流的增广路算法(KM算法). (poj1459,poj3436) 三.数据结构. (1)串(poj1035,poj3080,poj1936) (2)排序(快排、归并排(与逆序数有关)、堆排) (poj2388,poj2299) (3)简单并查集的应用. (4)哈希表和二分查找等高效查找法(数的Hash,串的Hash) (poj3349,poj3274,POJ2151,poj1840,poj2002,poj2503) (5)哈夫曼树(poj3253) (6)堆 (7)trie树(静态建树、动态建树) (poj2513) 四.简单搜索 (1)深度优先搜索(poj2488,poj3083,poj3009,poj1321,poj2251) (2)广度优先搜索(poj3278,poj1426,poj3126,poj3087.poj3414) (3)简单搜索技巧和剪枝(poj2531,poj1416,poj2676,1129) 五.动态规划 (1)背包问题. (poj1837,poj1276) (2)型如下表的简单DP(可参考lrj的书page149): 1.E[j]=opt{D+w(i,j)} (poj3267,poj1836,poj1260,poj2533) 2.E[i,j]=opt{D[i-1,j]+xi,D[i,j-1]+yj,D[i-1][j-1]+zij} (最长公共子序列) (poj3176,poj1080,poj1159) 3.C[i,j]=w[i,j]+opt{C[i,k-1]+C[k,j]}.(最优二分检索树问题) 六.数学 (1)组合数学:

ACM一期 基础训练计划

这个训练计划我也只是把我知道的知识点罗列出来而已. 其实acm还有很多方面的知识。 可能到acm生涯结束的时候还是无法把所有的知识都吃透 所以acm的知识能学多少算多少,知识重要的不是你知道的多,重要的是你能否熟练的运用他们! 题目注意事项: zoj:https://www.sodocs.net/doc/b615495354.html,/ grid:https://www.sodocs.net/doc/b615495354.html,/ hdu:https://www.sodocs.net/doc/b615495354.html,/ zquoj:也就是我们的oj 一.数据机构基础。 请自学完数据结构书:2,3,4,6,7,9.1,9.2.1 9.3 10 这几章,带*号可以暂时掠过,以后再看。然后自行完成oj DS开头的题目。 注意栈队列这些数据结构一般不用像书本那样写得那么严谨。在acm中,往往因为时间关系,一般写成简单的模式:请参考附件:栈与队列acm中的简单实现.txt 其它数据结构请自行简化。 二.其他数据结构 1.trie树 请看附件trie树的相关附件或到网上搜索。注意自己写好和简化模版。 Trie树最好使用静态分配实现! poj 3630 hdu 1251 2.并查集 Hdu:1558 1811 1829 1198 3.图论专题: 简单的说下图怎么存储。 图通常分为邻接表和邻接矩阵两种方式储存。 请先移步到数据结构书祥看这两种实现方式。 邻接表:我们知道要动态分配内存。这种方式有时会导致效率低下。我们可以模拟一下动态分配内存,详见附件静态分配。 这部分图论可参考 https://www.sodocs.net/doc/b615495354.html,/p-251720691.html 部分题目.这本书有讲解。 1.图的基本概念 poj:1659 2.图的遍历和活动问题 zoj:2110 1709 1649 2913 1060 2193 2412 1008 2165 1136 1361 1091 1083 poj:2935 1270 3687

acmicpc练习题

1、装箱问题:给定大小为S1,…,Sn的n个物件,其中0<Si≤1,寻找能够装进所有这些物件的最少数量的箱盒,每个箱盒容量为1。(提示:贪心法求解。) 2、已知一个包含n个元素的整型数组和一个整数K。试用O(NlogN)算法解决这样的问题:确定数组中是否存在两个数,它们的和等于给定的数K。一个数可以被使用两次。 例如,如果输入是8,5,2,7而K是12,则答案为yes(5和7)。 输入: 8 5 2 7 12 输出: yes 3、已知有2n个元素的无序数组a,试用O(n)算法将这2n个元素分别放入大小均为n的数组b和c。使得数组b中的所有元素均小于数组c中的任意元素。 输入: 5 7 10 4 2 6 9 1 8 3 5 输出: 4 2 1 3 5 7 10 6 9 8 (注意:输入第一行为1/2数组a的大小,第二行为数组a中的元素,输出时b、c数组中元素顺序不一定与示例一致)

4、令A为元素是0和1的N行N列矩阵。A的子矩阵S由形成方阵的任意一组相邻项组成。设计一种O(n2)算法,确定A中的全为1的最大子矩阵的阶数。 输入:(可以程序中初始化) 1 0 1 1 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 0 1 0 0 0 1 1 1 1 1 1 0 1 0 1 1 1 1 0 0 1 0 1 1 1 1 0 0 0 0 1 1 1 1 0 输出: 4 (输入:一个矩阵,输出:全为1的最大子矩阵阶数) (提示:动态规划解题。) 5、输入一批数据{34,27,56,12,25,78,94,36,58,90,66,77},从这 批数中找出最大值和第二大的值以及它们所在的位置。要求在同一个循环中既找出最大值又找出第二大值(只能使用一层循环)。不允许用排序的方法。 6、编写一个万年历程序。输入1900年后的某一年,要求显示该年份的日历, 日历以月份顺序排列,每月以星期顺序排列,类似于一般挂历上的格式。 7、一本书的页码从自然数1开始顺序编码直到自然数n。书的页码按照通常的 习惯编排,每个页码都不含多余的前导数字0。例如,第6页用数字6表示,而不是06或006等。数字计数问题要求编写程序对给定书的总页码n,计算出书的全部页码中分别用到多少次数字0,1,2,3,4,……9. 8、用给定的几种钱币凑成某个钱数,一般而言有多种方式。例如:给定了 6种钱币面值为2、5、10、20、50、100,用来凑15元,可以用5个2

(2020年编辑)ACM必做50题的解题-数论

poj 1061 青蛙的约会 这题用的是解线性同余方程的方法,之前没接触到过,搜索资料后看到一个人的博客里面讲的很好就拷贝过来了。内容如下: 对于方程:ax≡b(mod m),a,b,m都是整数,求解x 的值,这个就是线性同余方程。符号说明: mod表示:取模运算 ax≡b(mod m)表示:(ax - b) mod m = 0,即同余 gcd(a,b)表示:a和b的最大公约数 求解ax≡b(mod n)的原理:对于方程ax≡b(mod n),存在ax + by = gcd(a,b),x,y是整数。而ax≡b(mod n)的解可以由x,y来堆砌。具体做法如下: 第一个问题:求解gcd(a,b) 定理一:gcd(a,b) = gcd(b,a mod b) 欧几里德算法 int Euclid(int a,int b) { if(b == 0) return a; else return Euclid(b,mod(a,b)); } 附:取模运算 int mod(int a,int b) { if(a >= 0) return a % b; else return a % b + b; } 第二个问题:求解ax + by = gcd(a,b) 定理二:ax + by = gcd(a,b)= gcd(b,a mod b) = b * x' + (a mod b) * y' = b * x' + (a - a / b * b) * y' = a * y' + b * (x' - a / b * y') = a * x + b * y 则:x = y' y = x' - a / b * y' 以上内容转自https://www.sodocs.net/doc/b615495354.html,/redcastle/blog/item/934b232dbc40d336349bf7e4.html

Acm集训营培训心得

Acm集训营培训心得 参加暑期acm训练营的培训,让我收获了好多,感想也特别特别多,也学会了许多。所以特别感谢集训营中为我们上课的老师对我们做的培训。 经过特训营的培训,我了解到了许多关于acm的一系列知识。我感触特别深。作为ACM的新手,有兴趣而经验不足,然而有些热心的学者与老师多是向新手推荐书籍,如刘汝佳的算法竞赛入门经典,算法艺术与信息学竞赛及算法导论。不知这些是否是有针对ACM的系统教材,始终在这偌大的书籍中感到彷徨。但我觉得一方面它们倾向于理论证明、缺乏实战性,当时总是希望有位知识渊博的学者能带着我走。可这一切只是天方夜谭,更多的只能希冀在自己的身上。暑假集训从早上9点到下午5点,中间吃饭睡觉花掉3个小时左右,一天有6个小时上课时间,也许这段时间的确不是很长,每上五天课便会放假一天。看似好轻松,然而过于集中精力死盯这电脑屏幕,久而久之会有突如其来的疲倦。如果您想要从一个新手改造成一个合格的队员,你所感到的便是你的疯狂。引入ACM的历史,然后便是三道都是A+B,而且有样例程序培训,开始的第一节莫过于热身。这不仅能带给我们激情和勇气,同时看似基础性的东西却往往是胜败的关键点,使得我们不可松懈。接着便是从最简单的算法开始介绍,依次是:线性表,栈,队列,枚举法,递推法,递归法,分治法,树,搜索,图论的相关知识,并查集,动态规划,大数问题,字符串问

题。线性表,栈,队列:都有顺序结构和链式结构;栈和队列是在程序设计中被广泛使用的两种线性数据结构,它们的特点在于基本操作的特殊性,栈必须按"后进先出"的规则进行操作,而队列必须按"先进先出"的规则进行操作。和线性表相比,它们的插入和删除操作受更多的约束和限定,故又称为限定性的线性表结构。而这三者都是来自数据结构的知识,数据结构数据结构是介于数学、计算机硬件和计算机软件三者之间的一门核心课程。数据结构这一门课的内容不仅是一般程序设计(特别是非数值性程序设计)的基础,而且是设计和实现编译程序、操作系统、数据库系统及其他系统程序的重要基础。同时这门课程也是非常难学,需要我们花费更多的功夫。对于ACM的竞赛,更多的是注重于你对题目的灵活运用,采取比较简便的方法,所以便引入了枚举法,递推法,递归法,分治法,动态规划等技巧性较强的专门课程。复杂的ACM竞赛题往往蕴藏着精深的数学道理,需要的是数学知识的结合,学以灵活变通。就是这样才让人感觉到它是种让人从粗浅走向智慧,从蒙昧走向文明,从低级走向高级,从不完善走向完善的艰难历程。除了对这些学术上的专业注重,然而也需要学习英语知识,大多数的竞赛题目是英文,为了更加趋于国际化,英语也成为国际的交流语言,所以学习英语义不容辞,不可推卸。通过以上报告间隙,我结合自身学习实际,进行了客观的对比与反思。在今后的学生涯中,我要查漏补缺,通过学习来完善自身专业素养,努力为自己的梦想实践。

ACM训练计划

ACM常用算法及练习 第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码,因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打出来. 1.最短路(Floyd、Dijstra,BellmanFord) 2.最小生成树(先写个prim,kruscal要用并查集,不好写) 3.大数(高精度)加减乘除 4.二分查找. (代码可在五行以内) 5.叉乘、判线段相交、然后写个凸包. 6.BFS、DFS,同时熟练hash表(要熟,要灵活,代码要简) 7.数学上的有:辗转相除(两行内),线段交点、多角形面积公式. 8. 调用系统的qsort, 技巧很多,慢慢掌握. 9. 任意进制间的转换 第二阶段:练习复杂一点,但也较常用的算法。 如: 1. 二分图匹配(匈牙利),最小路径覆盖 2. 网络流,最小费用流。 3. 线段树. 4. 并查集。 5. 熟悉动态规划的各个典型:LCS、最长递增子串、三角剖分、记忆化dp 6.博弈类算法。博弈树,二进制法等。 7.最大团,最大独立集。 8.判断点在多边形内。 9. 差分约束系统. 10. 双向广度搜索、A*算法,最小耗散优先. 相关的知识 图论 路径问题 0/1边权最短路径 BFS 非负边权最短路径(Dijkstra) 可以用Dijkstra解决问题的特征 负边权最短路径 Bellman-Ford Bellman-Ford的Yen-氏优化 差分约束系统 Floyd 广义路径问题 传递闭包 极小极大距离/ 极大极小距离

Euler Path / Tour 圈套圈算法 混合图的Euler Path / Tour Hamilton Path / Tour 特殊图的Hamilton Path / Tour 构造 生成树问题 最小生成树 第k小生成树 最优比率生成树 0/1分数规划 度限制生成树 连通性问题 强大的DFS算法 无向图连通性 割点 割边 二连通分支 有向图连通性 强连通分支 2-SAT 最小点基 有向无环图 拓扑排序 有向无环图与动态规划的关系 二分图匹配问题 一般图问题与二分图问题的转换思路 最大匹配 有向图的最小路径覆盖 0 / 1矩阵的最小覆盖 完备匹配 最优匹配 稳定婚姻 网络流问题 网络流模型的简单特征和与线性规划的关系最大流最小割定理 最大流问题 有上下界的最大流问题 循环流 最小费用最大流/ 最大费用最大流

acm入门基础题解一

Problem A: 数字三角形 #include #include constintmaxn=110; int a[maxn][maxn],b[maxn][maxn],n; voiddata_set(){ for(int i=1;i<=n;i++){ for(int j=1;j<=i;j++){ scanf("%d",&a[i][j]); } } } void solve(){ for(int j=1;j<=n;j++) b[n][j]=a[n][j]; for(int i=n-1;i>=1;i--) for(int j=1;j<=i;j++){ if(b[i+1][j+1]>b[i+1][j]) b[i][j]=b[i+1][j+1]+a[i][j]; else b[i][j]=b[i+1][j]+a[i][j]; } printf("%d\n",b[1][1]);

} int main(){ while(scanf("%d",&n)!=EOF&&n!=0){ data_set(); solve(); } return 0; } Problem B: 去北京看奥运 #include #include constintmaxn=110; constintinf=200000000; int a[maxn],b[maxn][maxn],dp[maxn][maxn],n; voiddata_set(){ for(int j=0;j

整理出ACM所有题目及答案

1000 A + B Problem Problem Description Calculate A + B. Input Each line will contain two integers A and B. Process to end of file. Output For each case, output A + B in one line. Sample Input 1 1 Sample Output 2 Author HDOJ 代码: #include int main() { int a,b; while(scanf("%d %d",&a,&b)!=EOF) printf("%d\n",a+b); } 1001 Sum Problem Problem Description Hey, welcome to HDOJ(Hangzhou Dianzi University Online Judge). In this problem, your task is to calculate SUM(n) = 1 + 2 + 3 + ... + n. Input The input will consist of a series of integers n, one integer per line. Output For 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 Input 1 100 Sample Output 1

ACM必做50题——数学

1、POJ 2249 Binomial Showdown 组合数学。 高精度,也可把分子分母的数组进行两两约分 #include using namespace std; double c(int c,int k) { double a=1; int i,j=2; for(i=c;i>c-k;i--) a=a*i/(c-i+1); return a; } int main() { int n,k; while(scanf("%d%d",&n,&k)!=EOF && (n!=0 || k!=0)) { if(k>n/2 )k=n-k; printf("%.0lf\n",c(n,k)); } return 0; } 2、poj 1023 the fun number system (经典进位制) 题意:一种由2进制衍生出来的进制方法(我们暂且称为“类2进制”); 标明'n'的位置上原2进制该位的权重要乘上-1,才是现在进制方法该位的权重; 譬如说;pnp对于的能表示的数2来说就是110;即1*2^2+(-1)*1*2^1+1*2^0=2; 算法:这是数论中的进位制问题,我们可以仿照原来的求一个数二进制表示方法; 但首先,我们应该考虑几个问题; ①k位这种类2进制的表示范围; 显然,当给出的'p','n'序列中,我们将所有p的位置都置为1其余位是0,此时最大;当我们将所有n的位置置为1,其余为0,此时最小;不过当我们求最大限max和最小限min时会

有一个溢出问题;比如64位全是p的序列,那么max会溢出,值为-1;同理min在全是n 时也会溢出,为1;显然是max>=0,min<=1,溢出时产生异常,依次可以判断; ②是否是最大限和最小限之间的数都能表示呢? 都可以,而且能够表示的数是2^k个,这个原始2进制是一样的;因为每个位上要么是0,要么是1,而且每个位上的权重唯一的,不能通过其他位的01组合获得;最后,我们就可以仿照原始二进制来算在类2进制下的表示;不断求N的二进制最后一位和右移;如果取余是1,则该位上一定是1,如果该位对于字母为‘n’,则高位应该再加1;这里对2取余可能会出错,因为对于负数,补码的表示,最后一位一定是和原码一样的每次的右移后(有时需先加1)补码表示正好符合要求(可找实例验证); #include using namespace std; __int64 N,M; char s[100],res[100]={'\0'}; int main() { int T;scanf("%d",&T); int i,j; __int64 _max,_min; char ch; while(T--) { scanf("%I64d",&N); scanf("%s",s); _max=0;_min=0; for(i=0;i_max&&_max>=0)) puts("Impossible"); //注意防止64位数的溢出; else { memset(res,'\0',sizeof(res)); for(i=N-1;i>=0;i--) { int flag=0; if(M&1) //这里不能是平常的%2; { res[i]='1';

ACM集训队选拔赛第一场题目

Your job is to calculate the total score for a given user. Input The first line contains an integer np(1≤np≤300) which is the number of problems in Online Judge. The second line contains np integers representing the number of users who have solved this problem from problem 1000 to problem 1000+np-1. The third line contains an integers t(t≤10), which is the number of test cases. Each test case begins with an integer n, which is the number of problems the user has solved. Then it is followed by n distinct integers which are the problem ids. Problem id is labeled from 1000. Output For each test case, print the total score he can get on a single line. Sample Input 10 100 10 11 3 45 7 34 200 70 1 4 2 1000 1001 2 1001 1002 3 1000 1007 1008 Sample Output 12 18

整理出ACM所有题目及答案

1111111杭电: 1000 A + B Problem (4) 1001 Sum Problem (5) 1002 A + B Problem II (6) 1005 Number Sequence (8) 1008 Elevator (9) 1009 FatMouse' Trade (11) 1021 Fibonacci Again (13) 1089 A+B for Input-Output Practice (I) (14) 1090 A+B for Input-Output Practice (II) (15) 1091 A+B for Input-Output Practice (III) (16) 1092 A+B for Input-Output Practice (IV) (17) 1093 A+B for Input-Output Practice (V) (18) 1094 A+B for Input-Output Practice (VI) (20) 1095 A+B for Input-Output Practice (VII) (21) 1096 A+B for Input-Output Practice (VIII) (22) 1176 免费馅饼 (23) 1204 糖果大战 (25) 1213 How Many Tables (26) 2000 ASCII码排序 (32) 2001 计算两点间的距离 (34) 2002 计算球体积 (35) 2003 求绝对值 (36) 2004 成绩转换 (37) 2005 第几天? (38) 2006 求奇数的乘积 (40) 2007 平方和与立方和 (41) 2008 数值统计 (42) 2009 求数列的和 (43) 2010 水仙花数 (44) 2011 多项式求和 (46) 2012 素数判定 (47) 2014 青年歌手大奖赛_评委会打分 (49) 2015 偶数求和 (50) 2016 数据的交换输出 (52) 2017 字符串统计 (54) 2019 数列有序! (55) 2020 绝对值排序 (56) 2021 发工资咯:) (58) 2033 人见人爱A+B (59) 2037 今年暑假不AC (61) 2039 三角形 (63) 2040 亲和数 (64)

ACM训练指南

ACM练习建议 一位高手对我的建议: 一般要做到50行以内的程序不用调试、100行以内的二分钟内调试成功.acm 主要是考算法的 ,主要时间是花在思考算法上,不是花在写程序与debug上。 下面给个计划你练练: 第一阶段: 练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码,因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打 出来. 1.最短路(Floyd、Dijstra,BellmanFord) 2.最小生成树(先写个prim,kruscal要用并查集,不好写) 3.大数(高精度)加减乘除 4.二分查找. (代码可在五行以内) 5.叉乘、判线段相交、然后写个凸包. 6.BFS、DFS,同时熟练hash表(要熟,要灵活,代码要简) 7.数学上的有:辗转相除(两行内),线段交点、多角形面积公式. 8. 调用系统的qsort, 技巧很多,慢慢掌握. 9. 任意进制间的转换 第二阶段: 练习复杂一点,但也较常用的算法。 如: 1. 二分图匹配(匈牙利),最小路径覆盖 2. 网络流,最小费用流。 3. 线段树. 4. 并查集。 5. 熟悉动态规划的各个典型:LCS、最长递增子串、三角剖分、记忆化dp 6.博弈类算法。博弈树,二进制法等。 7.最大团,最大独立集。 8.判断点在多边形内。 9. 差分约束系统. 10. 双向广度搜索、A*算法,最小耗散优先. 第三阶段: 前两个阶段是打基础,第三阶段是锻炼在比赛中可以快速建立模型、想新算法 。这就要平时多做做综合的题型了。 1. 把oibh上的论文看看(大概几百篇的,我只看了一点点,呵呵)。

一些简单的acm题

【人民币问题】 Time Limit:1000MS Memory Limit:10000K Total Submit:574 Accepted:278 Description 给出任意的人民币(>10元)的整币兑换成5元、2元和1元币值(要求三种币值均有)的方法有多少种。 Input 输入任意的人民币(>10元)的整币100,50,20,10 Output 计算出兑换成5元、2元和1元币值(要求三种币值均有)的方法有多少种Sample Input 50 Sample Output 106 Source 【哥德巴赫曾猜测】 Time Limit:10000MS Memory Limit:65536K Total Submit:592 Accepted:194 Description 德国数学家哥德巴赫曾猜测:任何大于6的偶数都可以分解成两个素数(素数对)的

和。但有些偶数可以分解成多种素数对的和,如: 10=3+7,10=5+5,即10可以分解成两种不同的素数对。 Input 输入任意的>6的正偶数(<32767) Output 试求给出的偶数可以分解成多少种不同的素数对(注: A+B与B+A认为是相同素数对) Sample Input 1234 Sample Output 25 Source Code: #include #include using namespace std; int main() {int n;int z=0; int f(int); cin>>n; for(int i=2;i<=n/2;i++) { if(f(i)) {if(f(n-i)) {// cout<

来自牛人的ACM经验

来自牛人的ACM经验 竞赛2010-07-16 09:51:43 阅读0 评论0 字号:大中小 转于:https://www.sodocs.net/doc/b615495354.html,/luxuejuncarl/ hacker名单 https://www.sodocs.net/doc/b615495354.html,/isbx posted @ 2007-03-19 21:30 路雪军阅读(120) | 评论(0) | 编辑收藏 Linux常用命令锦集 https://www.sodocs.net/doc/b615495354.html,/images/tech/linux/zhuanti/mingling/index.htm posted @ 2007-03-19 20:25 路雪军阅读(112) | 评论(0) | 编辑收藏 2007年3月5日 随想 记录下wonderful的sentences,背下来并加以应用is a good habit.. posted @ 2007-03-05 15:24 路雪军阅读(88) | 评论(0) | 编辑收藏 2007年3月3日 acm比赛经验(转) 在天大,偶参加的比赛可以算是最多的了,说说比赛经验。 可能现在说早了点,需要大家在正式比赛之前再看一遍。 推荐此篇文章打印,与模板放在一起。 1. 比赛中评测会有些慢,偶尔还会碰到隔10分钟以上才返回结果的情况,这段时间不能等结果,必须开工其他题,如果W A,两道题同时做。交完每道题都要先打印。 2. 比赛时发的饭不是让你当时就吃的,那是给你赛后吃的。基本上比赛中前几名的队都没人吃,除非领先很多。 3. 很多选手,尤其是第一次参加比赛的,到一个新环境,全当旅游了,参观的参观,找同学的找同学,玩玩乐乐就把正事抛到脑后了,结果比赛自然没什么好成绩,这样的例子太多了。所以到参赛地后要时刻不忘自己是来比赛的,好好休息、备战。 4. 参赛前一天要睡10个小时以上,非常有助于保持比赛中的精力,很多时候比赛到3个多小时队员就没劲了就是这个原因。前一天晚饭与当天早饭要吃好,理由同上,要知道下顿饭得下午3点赛后才能吃。 5. 到新环境,时刻注意远离疾病,感冒肠炎病不大,却是成绩的天敌。 6. 英语不好,看不懂的,要勤查词典,懒一次就少一道题,远离奖牌。 7. 可以紧张,杜绝慌张,慌张是出题的敌人,任何时候,如果发现自己或者队友出现慌张的情况,提醒深呼吸。 8. 照着纸敲代码和sample数据时不要敲错,特别注意文字信息。 9. 第一道简单题交给队中最稳的人做,万一遇到麻烦也不要慌,如果有很多队都出了就更不必着急了,它必定是简单题,必定是可以很快做出来的,晚几分钟也比罚掉20分好。另外注意不要PE。 10. 最后一小时是出题高峰,谁松懈,谁落后。最后一小时出一道是正常,出两道更好。 以上各条均有出处,每条都包含着以往教训,每条都可能浪费掉你一年的努力,不可小视。以下各条有些来自于其他学校,有些是总结: 11. 无论是否有人通过,所有题必须全读过,最好每道题都有两人以上读过,尽量杜绝讲题

ACM数论方面十道基础题目详解

1、公约数和公倍数 https://www.sodocs.net/doc/b615495354.html,/JudgeOnline/problem.php?pid=40 这道题目是非常基础的题目,在学习了欧几里德算法之后,应该很好就能做的出来了。注意两个数的最小公倍数和最大公约数之间有关系为: a*b=gcd(a,b)*lcm(a,b); 代码如下: #include using namespace std; inline int Gcd(int m,int n) //求最大公约数 { if (m==0) return n; return Gcd(n%m,m); } int main() { int n,a,b,g; cin>>n; while(n--) { cin>>a>>b; g=Gcd(a,b); cout<

?????≡≡≡)33(mod ) 28(mod )23(mod d n e n p n 那么找到k1、k2、k3满足: k1:k1%23==0&&k1%28==0&&k1%33==1 k2:k2%33==0&&k2%28==0&&k2%23==1 k3:k3%33==0&&k3%23==0&&k3%28==1 则n=k2*p+k3*e+k1*i+k*21252; 代码如下: #include int main() { int n,a,b,c,t; while(scanf("%d%d%d%d",&a,&b,&c,&t),~a) { n=(5544*a+14421*b+1288*c)%21252-t; if(n<=0) n+=21252; printf("%d\n",n); } } 3、韩信点兵 https://www.sodocs.net/doc/b615495354.html,/JudgeOnline/problem.php?pid=34 这个题目也是很经典的中国剩余问题类的题目,思路跟上面差不多这道题目因为数据范围很小实际上暴力就可以过,但是这个题目不失为练习中国剩余的很好题目,所以建议大家用中国剩余定理做一下。 直接给出代码: 暴力求解代码: #include main() { int a,b,c,n; scanf("%d%d%d",&a,&b,&c); for(n=11;n<100;n++) if(n%3==a&&n%5==b&&n%7==c) printf("%d\n",n); } 中国剩余定理思路代码:

相关主题