http://acm.sdut.edu.cn/bbs/read.php?tid=135&page=e
ACM入门训练指南
管理提醒: 本帖被 yaoxu 执行置顶操作(2009-10-26)
目标读者:
想要在ACM/ICPC里进行发展,并通过SDUTOJ进行训练的初学者。
使用语言:
只要会一门程序设计语言,就可以进行ACM训练了。通过训练,可以更好地掌握语言使用能力、程序和算法设计能力。
使用语言:
只要会一门程序设计语言,就可以进行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是我们学校的在线评测系统。需要先在上面进行注册,注册后就可以进行题目的训练了。
点击主页上的“Problems”,就可以看到里面的题库,可以选任何一个题来做,里面的题目不是由易到难进行排列,而初学者要选择比较简单的题目来做。一般来讲,每道题目都有正确率ratio(AC/submit)——正确次数/提交总次数,那些正确率比较高并且提交次数比较多的就会比较简单。
一旦确定了做某道题,在读懂题意以后,就可以进行构思和编码了,编码完成后进行程序的调试。一般不直接在OJ的提交页面输入代码,而是先利用VC等开发环境进行程序的编译、调试和运行。因为即使编译成功的程序运行也不一定就正确,要用题目提供的样例输入数据(Sample Input)进行测试,如果结果和样例输出数据(Sample Output)不一致,就要对代码进行修改,直到能通过所有测试数据。初学者经常会碰到这样的问题:我的程序通过了Sample Input数据呀,为什么提交的时候仍然不正确呢?这是因为OJ系统中关于这道题目的测试数据远远不止这些,它还有许多你看不到的测试数据,你的程序必须要能通过它所有的数据,才算是正确的(Accepted)。如果有能力,需要根据题意自己设计一些测试数据来测试程序,以便保证提交的正确率。
下面挑出最简单的一个题(SDUTOJ1010)进行讲解:
A+B for Input-Output Practice (I)
Time Limit:1000MS Memory Limit:10000K(题目的运行时间和内存限制)
Total Submit:111 Accepted:36 (当前提交总次数 正确次数)
Description (题目描述)Your task is to Calculate a + b.
Too easy?! Of course! I specially designed the problem for acm beginners.
You must have found that some problems have the same titles with this one, yes, all these problems were designed for the same aim
Input (输入要求)
The input will consist of a series of pairs of integers a and b, separated by a space, one pair of integers per line.
Output (输出要求)
For each pair of input integers a and b you should output the sum of a and b in one line, and with one line of output for each line in input.
Sample Input (样例输入)
1 5
10 20
Sample Output (样例输出)
6
30
这是一个求两数之和的题目,输入用空格分开的两个数a b,输出a+b的结果。编写代码时需要注意的是,本题的输入数据不是只有一对数据,而是多对数据,每对数据占一行。因为没有指出共有多少对输入数据,于是我们可以编写如下代码:
//C语言
#include <stdio.h>
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 <iostream>
using namespace std;
int main()
{
int a,b;
while(cin >> a >> b)
cout << a+b << endl;
return 0;
}
}
在VC等环境下调试好程序后,在题目的下面有一个“Submit”选项,点击出现提交界面,可以把调试好的代码复制上去,注意选择的题号和语言(C选GCC,C++选G++)。如果没有登录则需要输入自己的帐号和密码后才可以进行提交,点击“submit”,出现题目状态列表(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 Exceed:程序产生了过多的输出信息,一般是由于死循环造成的。
10.没有这道题目(NSP)No such problem:提交了一个错误的题号或者这道题目不可用。
除了Accepted信息外,其他信息都说明你的程序有问题,还要进行修改然后提交,直到正确。
需要注意的问题:
OJ一般只支持标准输入输出,提交的程序不允许操作文件,你的程序不能输出任何多余信息,包括提示信息,如对上面1010号题的程序,可能会有些人这样写:
#include <stdio.h>
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里练习,如北大、杭电等,在论坛首页的友情链接里有他们的链接。多做题,多看书,不浮躁,不气馁,不懂要问,程序设计水平提高会很快的。
初学者可以先训练必须要掌握的知识和一些入门题,仅列举SDUTOJ中的题目:
1.输入输出练习:1000、1010-1017号题目;
2.学习C语言过程中,C语言实验题目:1110-1123,1151-1208;
3.刚学完一门语言,未学算法和数据结构的同学,可以做的简单题目:1044-1109。
[ 此帖被lxh在2009-04-07 23:33重新编辑 ]