【摘抄整理】算法竞赛入门经典(第2版)——语言篇(1-2章)
2016-07-27 10:58
399 查看
Wikipedia
C语言中文网
提示—整数值用%d输出,实数用%f输出
提示—整数/整数=整数,浮点数/浮点数=浮点数
提示—scanf中的占位符和变量的数据类型应一一对应,且每个变量前加’&‘字符
提示—const关键字表明值是不可改变的,用来声明常数
提示—pi=acos(-1.0)
提示—’acos‘返回的是一个数值的反余弦弧度值,其范围是 0~ pi 。 例如: acos(1) 返回值是 0
提示—’%lf‘相当于’double‘
提示—赋值是个动作,先计算右边的值,再赋给左边的变量,覆盖它原来的值
提示—printf的格式字符串中可以包含其他可打印符号,只有以’%‘开头的部分才会被后面的值替换掉,其他部分打印时原样输出
提示—’m%10‘值为m/10的余数
提示—’%03d‘一种左边补0 的等宽格式,比如数字12,%03d出来就是:012
提示—赋值a=b之后,变量a原来的值被覆盖,而b的值不变
输入n和m,依次输出鸡的数目和兔的数目,如果无解,则输出No answer
提示—if语句基本格式为:if(条件) 语句1;else 语句2
提示—if语句的条件是一个逻辑表达式,值可能为真,也可能为假。单个整数值也可以表示真假,其中’0‘为假,其他值为真
输入购买衣服件数,输出需要支付的金额(单位元),保留两位小数
如果可以,则输出yes,不能输出no,如果无法构成三角形,则输出 not a triangle
提示—for循环的格式为:for(初始化;条件;调整)循环体;
提示—尽量缩短变量的定义范围。例如:在for循环的初始化部分定义循环变量
aabb—7744问题
输出所有形如aabb的4位完全平方数
伪代码(pseudocode)
for(int a=1;a<=9;a++)
for(int b=1;b<=9;b++)
if(aabb是完全平方数)
printf(“%d\n”,aabb);
提示—’continue‘指直接进行下一次循环;’break‘指直接跳出循环
提示—’for(;;)‘是死循环,没有’break‘永远不会结束
对于任意大于1的自然数n,若n为奇数,则n→3n+1,否则n→n的一半。
经过若干次这样的变换,一定会使n变为1。例如3→10→5→16→8→4→2→1
输入n,输出变换的次数。n<=10^9
fe2c
。
样例输入:
3
样例输出:
7
提示—while循环的格式为:while(条件)循环体;
提示—在观察无法找出错误时,可以用“输出中间结果”的方法查错
提示—do-while循环的格式为:do{循环体}while(条件);
for(初始化;条件;调整)循环体;
||
初始化;
while(条件)
{
循环体;
调整;
}
近似计算
计算π/4 = 1- 1/3 + 1/5 - 1/7 + ….,直到最后一项小于10^-6
样例输入:
10
样例输出:
37913
提示—在循环开始处定义的变量,每次执行循环体时会重新声明并初始化
提示—要计算只包含加法、减法、乘法的整数表达式除以正整数n的余数,可以在每步计算后对n取余,结果不变
循环结构程序设计中最常见的两个问题:算术运算溢出和程序效率低下
输入一些整数,求出它们的最小值、最大值和平均值(保留3位小数)。
输出保证这些数都是不超过1000的整数
样例输入:
2 8 3 5 1 7 3 6
样例输出:
1 8 4.375
提示—在Windows下,输入完毕后先按Enter键,再按Ctrl+Z键,最后再Enter键,即可输入结束
提示—变量在未赋值之前的值是不确定的
算法竞赛入门经典 第二章 文件操作 重定向及fopen版本
输出保证这些数都是不超过1000的整数。
输入包含多组数据,每组数据第一行是整数个数n,第二行是n个整数。
n=0为输入结束标记,程序应当忽略这组数据。相邻两组数据之间应输出一个空行
样例输入:
8
2 8 3 5 1 7 3 6
4
-4 6 10 0
0
样例输出:
Case1:1 8 4.375
Case2:-4 10 3.000
提示—’t‘是当前编号计数器。当输出第2组或以后的结果时,会在前面加一个空行。
ACM输入输出
例如153 = 1^3 + 5^3 + 3^3,所以153是水仙花数。
输入3个非负整数a,b,c,表示每种队形排尾的人数(a<3,b<5,c<7)
输出总人数的最小值(或报告无解)。已知总人数不小于10,不超过100。
样例输入:
2 1 6
2 1 4
样例输出:
Case 1:41
Case 2:No Answer
输入包含多组数据,结束标记为a=b=c=0
样例输入:
1 6 4
0 0 0
样例输出:
Case 1: 0.1667
提示—printf的特殊用法,对于m.n的格式可以用如下方法表示:
char ch[20];
printf(“%*.*s\n”,m,n,ch);
前边的 * 定义的是总的宽度,后边的定义的是输出的个数。分别对应外面的参数m和n 。
这种方法的好处是可以在语句之外对参数m和n赋值,从而控制输出格式。
提示:不必太动脑筋
C语言中文网
程序设计入门
算术表达式
#include<stdio.h> int main() { printf("%d\n",1+2); return 0; }
#include<stdio.h> int main() { printf("%.1f\n",8.0/5.0); return 0; }
#include<stdio.h> #include<math.h> int main() { printf("%.8f\n",1+2*sqrt(3)/(5-0.1)); return 0; }
提示—整数值用%d输出,实数用%f输出
提示—整数/整数=整数,浮点数/浮点数=浮点数
变量及其输入
#include<stdio.h> int main() { int a,b; scanf("%d%d",&a,&b); printf("%d\n",a+b); return 0; }
提示—scanf中的占位符和变量的数据类型应一一对应,且每个变量前加’&‘字符
圆柱体表面积
#include<stdio.h> #include<math.h> int main() { const double pi=acos(-1.0); double r,h,s1,s2,s; scanf("%lf%lf",&r,&h); s1=pi*r*r; s2=2*pi*r*h; s=s1*2.0+s2; printf("Area=%.3f\n",s); return 0; }
提示—const关键字表明值是不可改变的,用来声明常数
提示—pi=acos(-1.0)
提示—’acos‘返回的是一个数值的反余弦弧度值,其范围是 0~ pi 。 例如: acos(1) 返回值是 0
提示—’%lf‘相当于’double‘
提示—赋值是个动作,先计算右边的值,再赋给左边的变量,覆盖它原来的值
提示—printf的格式字符串中可以包含其他可打印符号,只有以’%‘开头的部分才会被后面的值替换掉,其他部分打印时原样输出
三位数反转
#include<stdio.h> int main() { int m,n; scanf("%d",&m); n=(m%10)*100+(m/10%10)*10+(m/100); printf("%03d\n",n); return 0; }
提示—’m%10‘值为m/10的余数
提示—’%03d‘一种左边补0 的等宽格式,比如数字12,%03d出来就是:012
交换变量
#include<stdio.h> int main() { int a,b; scanf("%d%d",&a,&b); printf("%d %d\n",b,a); return 0; }
#include<stdio.h> int main() { int a,b,t; scanf("%d%d",&a,&b); t=a; a=b; b=t; printf("%d %d\n",a,b); return 0; }
提示—赋值a=b之后,变量a原来的值被覆盖,而b的值不变
鸡兔同笼
已知鸡和兔的总数量为n,总腿数位m。输入n和m,依次输出鸡的数目和兔的数目,如果无解,则输出No answer
#include<stdio.h> int main() { int n,m,a,b; scanf("%d%d",&n,&m); a=(4*n-m)/2; b=n-a; if(m%2==1||a<0||b<0)printf("No answer\n"); else printf("%d %d\n",a,b); return 0; }
提示—if语句基本格式为:if(条件) 语句1;else 语句2
提示—if语句的条件是一个逻辑表达式,值可能为真,也可能为假。单个整数值也可以表示真假,其中’0‘为假,其他值为真
三整数排序
#include<stdio.h> int main() { int a,b,c; scanf("%d%d%d",&a,&b,&c); if(a<=b&&b<=c) printf("%d %d %d\n",a,b,c); else if(a<=c&&c<=b) printf("%d %d %d\n",a,c,b); else if(b<=a&&a<=c) printf("%d %d %d\n",b,a,c); else if(b<=c&&b<=a) printf("%d %d %d\n",b,c,a); else if(c<=a&&a<=b) printf("%d %d %d\n",c,a,b); else if(c<=b&&b<=a) printf("%d %d %d\n",c,b,a); return 0; }
#include<stdio.h> int main() { int a,b,c,t; scanf("%d%d%d",&a,&b,&c); if(a>b) { t=a; a=b; b=t; }//执行完毕后a<=b if(a>c) { t=a; a=c; c=t; }//执行完毕后a<=c,且a<=b if(b>c) { t=b; b=c; c=t; } printf("%d %d %d\n",a,b,c); return 0; }
平均数(average)
输入3个整数,输出它们的平均值,保留3位小数:#include<stdio.h> void main() { int a,b,c; scanf("%d%d%d",&a,&b,&c); double avg = (a + b + c) / 3.0; printf("%.3lf\n",avg); }
#include <stdio.h> double average(int a,int b,int c); void main() { int a,b,c; scanf("%d%d%d",&a,&b,&c); double z= average(a,b,c); printf("%.3lf\n",z); } double average(int a,int b,int c) { return (a+b+c)/3; }
温度(temperature)
输入华氏温度f,输出对应的摄氏温度c,保留三位小数。c=5(f-32)/9#include <stdio.h> void main() { double f,c; scanf("%lf",&f); c=5*(f-32)/9; printf("%.3lf\n",c); }
连续和(sum)
输入正整数n,输出1+2+…+n的值。#include <stdio.h> int main() { int n; scanf("%d",&n); printf("%d\n",(n*(1+n))/2); return 0; }
正弦(sin)和余弦(cos)
输入正整数 n(n<360),输出n度的正弦余弦数值。#include <stdio.h> #include <math.h> int main() { const double pi=acos(-1.0); int n; scanf("%d",&n); if(n<360) { printf("%lf\n",sin((pi*n)/180)); printf("%lf\n",cos((pi*n)/180)); } return 0; }
打折(discount)
一件衣服 95元,若消费满300元,可打八五折。输入购买衣服件数,输出需要支付的金额(单位元),保留两位小数
#include <stdio.h> int main() { int n; double m; scanf("%d",&n); m=n*95; if(m>300) { m=m*0.85; } printf("%.2lf\n",m); return 0; }
三角形(triangle)
输入三角形 3 条边长度值(均为正整数),判断是否能为直角三角形的3个边长。如果可以,则输出yes,不能输出no,如果无法构成三角形,则输出 not a triangle
#include <stdio.h> int main() { int a,b,c; scanf("%d%d%d",&a,&b,&c); if(a+b<=c||a+c<=b||b+c<=a) { printf("not a triangle\n"); return 0; } if(a*a+b*b==c*c||a*a+c*c==b*b||b*b+c*c==a*a) printf("yes\n"); else printf("no\n"); return 0; }
年份(year)
输入年份,判断是否为润年,如果是,输出yes,否,输出no。#include <stdio.h> int main() { int n; scanf("%d",&n); if(n%4==0 && n%100!=0 || n%400==0) printf("yes\n"); else printf("no\n"); return 0; }
循环结构程序设计
for循环
输出1,2,3…,n的值#include<stdio.h> int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { printf("%d\n",i); } return 0; }
提示—for循环的格式为:for(初始化;条件;调整)循环体;
提示—尽量缩短变量的定义范围。例如:在for循环的初始化部分定义循环变量
aabb—7744问题
输出所有形如aabb的4位完全平方数
伪代码(pseudocode)
for(int a=1;a<=9;a++)
for(int b=1;b<=9;b++)
if(aabb是完全平方数)
printf(“%d\n”,aabb);
#include<stdio.h> #include<math.h> int main() { for(int a=1;a<=9;a++) { for(int b=1;b<=9;b++) { int n=a*1100+b*11; int m=floor(sqrt(n)+0.5); if(m*m==n) { printf("%d\n",n); } } } return 0; }
#include<stdio.h> int main() { for(int m=1;;m++) { int n=m*m; if(n<1000) continue; if(n>9999) break; int a=n/100; int b=n%100; if(a/10==a%10 && b/10==b%10) printf("%d\n",n); } return 0; }
提示—’continue‘指直接进行下一次循环;’break‘指直接跳出循环
提示—’for(;;)‘是死循环,没有’break‘永远不会结束
while循环和do-while循环
3n+1问题对于任意大于1的自然数n,若n为奇数,则n→3n+1,否则n→n的一半。
经过若干次这样的变换,一定会使n变为1。例如3→10→5→16→8→4→2→1
输入n,输出变换的次数。n<=10^9
fe2c
。
样例输入:
3
样例输出:
7
#include<stdio.h> int main() { int n2,count=0; scanf("%d",&n2); long long n=n2; //c99 while(n>1) { if(n%2==1) n=n*3+1; else n=n/2 count++; } printf("%d\n",count); return 0; }
#include<stdio.h> int main() { int n,count=0; scanf("%d",&n); while(n>1) { if(n%2==1) { n=n*3+1; //printf("%d\n",n); //测试用;输入987654321时n为-1332004332,这种情况为**乘法溢出** } else { n=n/2; //printf("%d\n",n); } count++; } printf("%d\n",count); return 0; }
提示—while循环的格式为:while(条件)循环体;
提示—在观察无法找出错误时,可以用“输出中间结果”的方法查错
提示—do-while循环的格式为:do{循环体}while(条件);
for(初始化;条件;调整)循环体;
||
初始化;
while(条件)
{
循环体;
调整;
}
近似计算
计算π/4 = 1- 1/3 + 1/5 - 1/7 + ….,直到最后一项小于10^-6
#include<stdio.h> int main() { double sum=0; for(int i=0;;i++) { double t=1.0/(i*2+1); if(i%2==0) sum+=t; else sum-=t; if(t<1e-6)break; } printf("%.6f\n",sum); return 0; }
阶乘之和
输入n,计算S=1!+2!+3!+…+n!的末六位(不含前导0)。n<=10^6。样例输入:
10
样例输出:
37913
#include<stdio.h> int main() { const int MOD=1000000; int n,S=0; scanf("%d",&n); if(n>25)n=25; for(int i=1;i<=n;i++) { int factorial=1;//factorial阶乘 for(int j=1;j<=i;j++) { factorial=factorial*j%MOD; } S=(S+factorial)%MOD; } printf("%d\n",S); return 0; }
提示—在循环开始处定义的变量,每次执行循环体时会重新声明并初始化
提示—要计算只包含加法、减法、乘法的整数表达式除以正整数n的余数,可以在每步计算后对n取余,结果不变
循环结构程序设计中最常见的两个问题:算术运算溢出和程序效率低下
数据统计1
(书P28-P33)输入一些整数,求出它们的最小值、最大值和平均值(保留3位小数)。
输出保证这些数都是不超过1000的整数
样例输入:
2 8 3 5 1 7 3 6
样例输出:
1 8 4.375
#include<stdio.h> #define INF 1000000000 int main() { int x,n=0, min=INF,max=-INF,sum=0; while(scanf("%d",&x)==1) //scanf的返回值为读入的数据个数,while(scanf("%d",&n)==1)在成功读入1个数据时执行循环体。 { sum+=x; if(x<min)min=x; if(x>max)max=x; n++; } printf("%d %d %.3f\n",min,max,(double)sum/n); return 0; }
提示—在Windows下,输入完毕后先按Enter键,再按Ctrl+Z键,最后再Enter键,即可输入结束
提示—变量在未赋值之前的值是不确定的
算法竞赛入门经典 第二章 文件操作 重定向及fopen版本
数据统计2
输入一些整数,求出它们的最小值、最大值和平均值(保留3位小数)。输出保证这些数都是不超过1000的整数。
输入包含多组数据,每组数据第一行是整数个数n,第二行是n个整数。
n=0为输入结束标记,程序应当忽略这组数据。相邻两组数据之间应输出一个空行
样例输入:
8
2 8 3 5 1 7 3 6
4
-4 6 10 0
0
样例输出:
Case1:1 8 4.375
Case2:-4 10 3.000
#include<stdio.h> #define INF 1000000000 int main() { int x,n=0, min=INF,max=-INF,t=0; while(scanf("%d",&n)==1&&n) { int sum=0; for(int i=0;i<n;i++) { scanf("%d",&x); sum+=x; if(x<min)min=x; if(x>max)max=x; } if(t)printf("\n"); printf("Case %d: %d %d %.3f\n",++t,min,max,(double)sum/n); } return 0; }
提示—’t‘是当前编号计数器。当输出第2组或以后的结果时,会在前面加一个空行。
ACM输入输出
水仙花数(daffodil)
输出100 ~ 999中的所有水仙花数,若3位数ABC满足ABC = A^3 + B^3 + C^3,则称其为水仙花数。例如153 = 1^3 + 5^3 + 3^3,所以153是水仙花数。
#include<stdio.h> int main() { int a,b,c; for(int i=100;i<=999;i++) { a=i/100; b=i/10%10; c=i%10; if(i == a*a*a + b*b*b + c*c*c) printf("%d\n",i); } return 0; }
韩信点兵(hanxin)
韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排、五人一排、七人一排地变换队形,而他每次都只是掠一眼队伍的排位就知道人数了。输入3个非负整数a,b,c,表示每种队形排尾的人数(a<3,b<5,c<7)
输出总人数的最小值(或报告无解)。已知总人数不小于10,不超过100。
样例输入:
2 1 6
2 1 4
样例输出:
Case 1:41
Case 2:No Answer
#include<stdio.h> int main() { int a,b,c,n=0; while(scanf("%d%d%d",&a,&b,&c)==3 && a>0 && b>0 && c>0 && a<3 && b<5 && c<7) { for(int i=10;i<=100;i++) { if(i%3==a && i%5==b && i%7==c) { printf("Case %d:%d\n",++n,i); break; } } if(i==101) printf("Case %d:No answer\n",++n); } return 0; }
倒三角形(triangle)
输入正整数n<=20,输出一个n层的倒三角形。#include <stdio.h> int main() { int n; scanf("%d",&n); for(int i=n;i>=1;i--) { for(int j=1;j<=n-i;j++) printf(" "); for(j=1;j<=2*i-1;j++) printf("#"); printf("\n"); } return 0; }
子序列的和(subsequence)
输入两个正整数n#include<stdio.h> #include <math.h> int main() { int m,n,j=1; while(scanf("%d%d",&n,&m)!=EOF && n<m && m<pow(10.0,6.0)) { double sum = 0; if(m==0 && n==0) return 0; else { for(int i=n; i<=m; i++) { sum += ((1.0/i)*(1.0/i)); //分式运算把分子或分母写成浮点型,让其自动转化成小数。 } printf("Case %d: %.5f\n",j++,sum); } } return 0; }
分数化小数(decimal)
输入正整数a,b,c,输出a/b的小数形式,精确到小数点后c位。a,b<=10^6,c<=100输入包含多组数据,结束标记为a=b=c=0
样例输入:
1 6 4
0 0 0
样例输出:
Case 1: 0.1667
#include<stdio.h> #include <math.h> int main() { int a,b,c,j=1; scanf("%d%d%d",&a,&b,&c); if(a<=pow(10.0,6.0) && b<=pow(10.0,6.0) && c<=100) printf("Case %d: %.*lf\n",j++,c,(double)a/b); return 0; }
提示—printf的特殊用法,对于m.n的格式可以用如下方法表示:
char ch[20];
printf(“%*.*s\n”,m,n,ch);
前边的 * 定义的是总的宽度,后边的定义的是输出的个数。分别对应外面的参数m和n 。
这种方法的好处是可以在语句之外对参数m和n赋值,从而控制输出格式。
排列(permutation)
用1,2,3,···,9 组成 3 个三位数 abc,def和ghi,每个数字恰好使用一次,要求abc:def:ghi=1:2:3。输出所有解。提示:不必太动脑筋
#include <stdio.h> void main() { int a,b,c,d,e,f,g,h,i; for(a=1;a<=9;a++) for(b=1;b<=9;b++) for(c=1;c<=9;c++) for(d=1;d<=9;d++) for(e=1;e<=9;e++) for(f=1;f<=9;f++) for(g=1;g<=9;g++) for(h=1;h<=9;h++) for(i=1;i<=9;i++) if((2*(a*100+b*10+c)==1*(d*100+e*10+f)) &&(3*(a*100+b*10+c)==1*(g*100+h*10+i)) &&(a!=b)&&(a!=c)&&(a!=d)&&(a!=e)&&(a!=f)&&(a!=g)&&(a!=h)&&(a!=i) &&(b!=c)&&(b!=d)&&(b!=e)&&(b!=f)&&(b!=g)&&(b!=h)&&(b!=i) &&(c!=d)&&(c!=e)&&(c!=f)&&(c!=g)&&(c!=h)&&(c!=i) &&(d!=e)&&(d!=f)&&(d!=g)&&(d!=h)&&(d!=i) &&(e!=f)&&(e!=g)&&(e!=h)&&(e!=i) &&(f!=g)&&(f!=h)&&(f!=i) &&(g!=h)&&(g!=i) &&(h!=i)) printf("%d,%d,%d\n",a*100+b*10+c,d*100+e*10+f,g*100+h*10+i); }
相关文章推荐
- java.net.UrlConnection类的使用
- poj 3041 Asteroids( 最小顶点覆盖,二分图)
- Flume+Kafka+Storm+Redis实时分析系统基本架构
- 数据结构实验之链表一:顺序建立链表
- 替代setLatestEventInfo()的方法
- POJ 2507Crossed ladders(二分)
- SQL Server Primary Key和Clustered Index
- LNCS用户写作指南【 Springer Computer Science Proceedings 】
- vsftpd,nfs,samba
- iClient for JavaScript求两线交点、线线打断、点打断线
- 关于Android下各个布局方式里面LayoutParams的用法
- (POJ3469)Dual Core CPU 网络流最小割,Dinic模板应用
- 连接优化查询,按条件查询的时候,如何优化查询的时间
- scala 泛型之初解,定界,类型约束,逆变与协变
- KMP算法中的next数组求解示意图
- hdu 5755 Gambler Bo 高斯消元
- 统计字符串中0和1出现最多的个数
- iOS中nil 、NULL、 Nil 、NULL的区别
- 绝对公平?破解北京机动车摇号的秘密
- UML类图与类的关系