您的位置:首页 > 其它

算法竞赛入门经典_3.1_数组_逆序输出_开灯问题

2017-11-23 12:51 337 查看
又是新的一天,继续更新.
今天进入了新的章节,数组和字符串

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
4000
<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)在很多情况下,最好是在一件事之前检查是不是可以做,而不是在做完之后再后悔,因为"悔棋"往往是比较麻烦的.

发现做算法,其中还是可以学到很多,而且很有趣

生活中也是,我们在做某件事的时候,要考虑是不是应该做,因为后悔药是很难买的,就好比博主熬夜写博客,

现在还是可以接受的,如果天天如此身体也是会吃不消的,好了今天到这里了,各位同行们也早点休息,注意身体.

晚安世界!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: