竞赛初入门,发现题目是真的挺难的,一道题目看下来完全不知道在说什么,或者是没头绪,看了答案之后才慢慢能理解,嘛,一步一步来吧。
- 开灯问题,有n盏灯,编号为1-n, 第一个人把所有的灯都打开,第二个人按下所有编号为2的倍数的开关(这些灯将被关掉),第三个人按下所有编号为3倍数的开关(其中关掉的灯将被打开,开着的灯将被关闭),以此类推,一共有k个人,问最后有哪些灯开着?输入n和k,输出开着的灯的编号,k <= n <= 1000.
样例输入:
7 3
样例输出:
1 5 6 7
分析:这里直接用双重循环模拟操作,开着的关掉,关掉的打开,也就是逻辑或运算,而每次一个人开关的灯也可以用取余运算来解决。值得注意的是,第一个灯打开之后就不会关掉了。并且,输出的第一个灯的编号前面不能有空格。源代码如下:
#include <stdio.h> #include <string.h> #define maxn 1010 int a[maxn]; int main(void) { int lantern, person, first = 0; memset(a, 0, sizeof(a)); scanf("%d%d", &lantern, &person); for(int i = 1; i <= person; i++) for(int j = 1; j <= lantern; j++) if(j % i == 0) a[j] = !a[j]; for(int i = 1; i <= lantern; i++)) if(a[i]) { if(first) first = 0; else printf(" "); printf("%d", i); } printf("\n"); return 0; }
- 蛇形填数:在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. 分析: 这个的话其实不难,模拟一下就好了,先将矩阵(二维数组)都初始化为0(方便做判断),注意不要越界。且要把第一个数字直接先标记成1。
#include <stdio.h> #define maxn 20 int a[maxn][maxn]; int main(void) { int n, x, y; memset(a, 0, sizeof(a)); scanf("%d", &n); tot = a[x = 1][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; }
以上。大概就是这样子。