竞赛初入门,发现题目是真的挺难的,一道题目看下来完全不知道在说什么,或者是没头绪,看了答案之后才慢慢能理解,嘛,一步一步来吧。
- 开灯问题,有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("
");
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("
");
}
return 0;
}
以上。大概就是这样子。