exa3.0
1 /**
2 * output the input numbers in reverse order.
3 */
4 #include<stdio.h>
5 #define MAXN 100 +10
6 int main()
7 {
8 int a[MAXN];
9 int i, x,n=0;
10 while (scanf("%d",&x)==1)
11 {
12 a[n++]=x;
13 }
14 for(i=n-1;i>=1;i--) printf("%d ",a[i]);
15 printf("%d\n",a[0]);
16 return 0;
17 }
注意:
1.数组的大小往往不会精确给出,要习惯于开稍微大一点的数组--保险。
2.数组存到数组之后要注意前面N-1个数 中间用空格隔开就行,而最后一个数(行尾)应该又换行!
回忆之前的规定:
算法竞赛中每行输出最后应以回车符结束,包括最后一行。
除非特别说明,每行行首不应有空格,但行末通常可以有多余的空格。
此外,输出的两个数或者字符串之间应该用单个空格隔开。
3.把上面的程序MAXN改为1000000 会在运行时报错段错误 (核心已转储)
---》 比较大的数组应该声明在main之外!
4.数组不能够进行赋值操作 比如 int a[MAXN], b[MAXN]
不能直接a=b 而要借助memcpy()
复制整个整形数组:memcpy(b,a,sizeof(a))
复制整形数组前k个元素: memcpy(b,a,sizeof(int)*k)
复制浮点型数组前k个元素:memcpy(b,a,sizeof(double)*k)
此外使用memcpy需要包含头文件string.h
exa3-1 开灯问题
有n盏灯,编号1-n。第一个人把所有灯打开,第二个人按下所有编号为2的倍数的开关(这些灯被关),第三个人按下所有编号为3的倍数的开关。。。
以此进行下去一共有k个人,问最后有哪些灯开着? 输入n,k,输出开着的灯的编号 。 k<n<1000.
样例输入: 7 3
样例输出:1 5 6 7
1 #include<stdio.h>
2 #include<string.h>
3 #define MAXN 1000+10
4 int a[MAXN];
5 int main()
6 {
7 int i,j,n,k,first=1;
8 memset(a,0,sizeof(a));
9 scanf("%d%d", &n,&k);
10 for(i=1;i<=k;i++)
11 for(j=1;j<=n;j++)
12 if(j%i==0) a[j]=!a[j];
13 for(i=1;i<=n;i++)
14 if(a[i]){if(first)first =0; else printf(" ");printf("%d",i);}
15 printf("\n");
16 return 0;
17 }
备注:
1.memset(a,0,sizeof(a)) 作用是将整个数组a初始化为0,也在string,h中定义。 比for循环赋值来的简洁!
2.为了避免输出多余空格,设置一个标志变量first 判断当前输出的变量是否为第一个。 第一个变量前不应有空格。
《我觉得其实直接每个变量后面加空格应该也是可以的。》
3.由于只有0和1两种取值,所以 a=!a是很简洁的算法。如果有两种取值0, b ,那么 a=b-0就很好!
4,注意由于灯的数量是确定的,也就是说上届是确定的,这时候的倍数关系用求余处理比较方便。如果用乘法处理会比较麻烦。
exa3-3 蛇形填数
在n *n方阵里填入1,2,...,n*n,要求填成蛇形。例如n=4时方阵为:
10 11 12 1
9 16 13 2
8 15 14 3
7 6 5 4
n<=8.
1 #include<stdio.h>
2 #include<string.h>
3 #define MAXN 10
4 int a[MAXN][MAXN];
5 int main()
6 {
7 int n,x,y,tot=0;
8 scanf("%d",&n);
9 memset(a,0,sizeof(a));
10 tot=a[x=0][y=n-1]=1;
11 while(tot<n*n)
12 {
13 while(x+1<n && !a[x+1][y]) a[++x][y]=++tot;
14 while(y-1>=0 && !a[x][y-1]) a[x][--y]=++tot;
15 while(x-1>=0 && !a[x-1][y]) a[--x][y]=++tot;
16 while(y+1<n && !a[x][y+1]) a[x][++y]=++tot;
17 }
18 for(x=0;x<n;x++)
19 {
20 for(y=0;y<n;y++)printf("%4d", a[x][y]);
21 printf("\n");
22 }
23 return 0;
24 }
1.这段程序利用了C语言的简洁优势。
比如!a[x+1][y] 判断这个数是不是0;a[++x][y]=++tot; 同时完成赋值和x,tot的增加。
还有tot=a[x=0][y=n-1]=1 同时完成了x,y 的赋值 和tot a[0][n-1] 的赋值!
2.移动的原则是:先预判,再移动。
边界确定的时候一定要细心,再就是++放在前面还是后面也要仔细考虑。