算法竞赛入门经典_3.1_数组_逆序输出_开灯问题
Posted easydots的博客园
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法竞赛入门经典_3.1_数组_逆序输出_开灯问题相关的知识,希望对你有一定的参考价值。
又是新的一天,继续更新.
今天进入了新的章节,数组和字符串
1.逆序输出问题:
先来看代码吧
#include <stdio.h> //逆序输出 2017-8-16 #define maxn 105 int a[maxn]; int main(int argc, char* argv[]) { //int a[maxn]; int x, n = 0; while (scanf("%d", &x) == 1) a[n++] = x; for (int i = n - 1; i >= 1; i--) printf("%d ", a[i]); printf("%d\\n", a[0]);//输出的行首和行尾一般均无空格,所以用两条语句实现输出 return 0; }
注意:数组一般会声明得稍大一些
这是一个逆序输出问题,但需要注意的是在定义数组的时候,要在main函数之外定义,如果遇到maxn很大,如1000000,则程序将无法运行,下面截图为证
直接结束了,所以我们应该放外面,再看
放外面就正常运行了,然后看看效果截图吧
2.开灯问题:
看代码
//开灯问题 2017-8-16 #include <stdio.h> #include <string.h> #define maxn 1010 int a[maxn]; int main(int argc, char* argv[]) { int n, k, first = 1; memset(a, 0, sizeof(a)); scanf("%d%d", &n, &k); for (int i = 1; i <= k; i++) for (int j = 1; j <= n; j++) if (j % i == 0) a[j] = !a[j]; for(int i = 1; i <= n; i++) if(a[i]) { if (first) first = 0; else printf(" "); printf("%d", i); } printf("\\n"); return 0; }
这里有很多新的知识点了,首先是string.h中的memcpy(b,a,sizeof(int)*k)是将a数组复制给b,大小为k,
如果想全部复制,可以使用memcpy(b,a,sizeof(a)),还有一个函数,也就是本程序出现的memset(a, 0, sizeof(a));
是将数组a中的数据置为0.
值得注意的是,我们定义了first变量,这个变量是干什么的呢?很显然它是一个标志是否是第一个数据的变量,
因为在输出的时候,第一个数前面是不需要空格的.
看运行结果
3.蛇形填数:
这个问题博主还没解决,不知道为什么和书上代码一样,运行却有问题
搞笑了,博主刚好想贴代码的时候检查了下代码,发现是第22while循环条件搞错了,应该是向上移动x-1 >= 0(我之前写成了<,这告诉大家,写代码如果遇到了一些很奇怪的运行结果,试着检查自己的代码,特别是循环条件)
//蛇形填数问题 2017-8-16 #include <stdio.h> #include <string.h> #define maxn 20 int a[maxn][maxn]; int main() { int n, x, y, tot = 0; scanf("%d", &n); memset(a, 0, sizeof(a)); x = 0; y = n - 1; a[x][y] = 1; tot = 1; //tot = a[x = 0][y = n - 1] = 1;//这条语句很简洁,也可以使用这句替代上面的四条语句 while (tot < n*n) { while (x + 1 < n && !a[x + 1][y]) a[++x][y] = ++tot; while (y - 1 >= 0 && !a[x][y - 1]) a[x][--y] = ++tot; while (x - 1 >= 0 && !a[x - 1][y]) a[--x][y] = ++tot; while (y + 1 < n && !a[x][y + 1]) a[x][++y] = ++tot; } for (x = 0; x < n; x++) { for (y = 0; y < n; y++) printf("%3d", a[x][y]); printf("\\n"); } return 0; }
分析:从1开始填写,设置笔的起始坐标为(x,y),也就是(0,n-1)了,x代表行,y代表列,所以笔的移动轨迹是下,下,下,左,左,左,上,上,上,右,右,下,下,左,上
在这里我们只需要判断两个条件
- 一个是是否超出边界,在下移动的轨迹中,也就是x+1<n
- 另一个是是否填了以前填过得格子,所以是a[x+1][y] == 0的条件,简写为!a[x+1][y]
有了这一思路,就好解了看运行结果吧
在这一练习中,我们可以学到的:
1)可以利用c语言简洁的语法,但前提是保持代码的可读性
2)在很多情况下,最好是在一件事之前检查是不是可以做,而不是在做完之后再后悔,因为"悔棋"往往是比较麻烦的.
发现做算法,其中还是可以学到很多,而且很有趣
生活中也是,我们在做某件事的时候,要考虑是不是应该做,因为后悔药是很难买的,就好比博主熬夜写博客,
现在还是可以接受的,如果天天如此身体也是会吃不消的,好了今天到这里了,各位同行们也早点休息,注意身体.
晚安世界!
以上是关于算法竞赛入门经典_3.1_数组_逆序输出_开灯问题的主要内容,如果未能解决你的问题,请参考以下文章