开灯和蛇形

竞赛初入门,发现题目是真的挺难的,一道题目看下来完全不知道在说什么,或者是没头绪,看了答案之后才慢慢能理解,嘛,一步一步来吧。

  • 开灯问题,有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;
}

以上。大概就是这样子。

posted @ 2018-03-08 23:09  jckcoenf  阅读(118)  评论(0编辑  收藏  举报