周日晚上,和儿子一起学习,前面学习的排序,需要应用一下,因此在洛谷上找了一个最简单的入门排序问题。结果,很不理想,做完后,提交测试,只能得60分。前后修改了4次。中间出现了各种问题,最终才搞定。
记录失败,分析原因,我将这次的过程记录下来,希望对儿子能有促进。
先看题目:洛谷P1152,排序中的入门题目。
题目描述
一个 n 个元素的整数数组,如果数组两个连续元素之间差的绝对值包括了 之间的所有整数,则称之符合“欢乐的跳”,如数组 {1,4,2,3} 符合“欢乐的跳”,因为差的绝对值分别为:3,2,1。给定一个数组,你的任务是判断该数组是否符合“欢乐的跳”。
输入格式
每组测试数据第一行以一个整数 n 开始,接下来 n个空格隔开的在 之间的整数。
输出格式
对于每组测试数据,输出一行若该数组符合“欢乐的跳”则输出 Jolly,否则输出 Not jolly。
输入输出样例
输入
4 1 4 2 3
输出
Jolly
输入
5 1 4 2 -1 6
输出
Not jolly
说明/提示
1≤n≤1000
阅读题目后,我简单给他分析了一下题目,然后就开始做。
还算比较顺利的完成了第一版。自己测试也通过了,很高兴。
我们看看第一版的程序。(注释是我加的)
#includebits/stdc++.h
using namespace std;
int main()
{
int n=0;
int a[1005];
int c=0;
int y=0;
cinn;
for
{
cina[i];
if(a[i]0)
{
a[i]=a[i]*-1;
}
}
//冒泡排序,首先要注意的是,外循环从大到小,内循环,从小到大
for
{
for
{
if(a[j]a[j+1]) //比大小,如果前面的大,就交换位置
{
c=a[j+1];
a[j+1]=a[j];
a[j]=c;
}
}
}
//这一部分是有问题的,后面会分析为什么错了
for
{
if(a[i+1]-a[i]==0)
{
continue;
}
if(a[i+1]-a[i]!=1)
{
y=1;
break;
}
}
if(y==1)
{
cout"Not jolly";
}
else
{
cout"Jolly";
}
return 0;
}
提交洛谷,一看,只有60分。
上图红色的表示这个测试点没有通过,说明有地方没有考虑到。
我们边看程序边分析,发现排序之后的判断是否是Jolly的循环部分有问题,没有覆盖1~(n-1) 。
第1次,修改如下:
for
{
if(i!=a[i])
{
y=1;
break;
}
}
结果还是一样。
第2次修改,再次分析,推测没有覆盖不是从1开始的数组。再次修改这一部分。
for
{
if
{
y=1;
break;
}
}
提交后,还是一样,两人大眼瞪小眼,傻眼了,然后我们重头读题,重于发现,“如果数组两个连续元素之间差的绝对值”,而我们的代码中是排序后再判断差,这个肯定不行。
第3次修改。
完整代码如下:
#includebits/stdc++.h
using namespace std;
int main()
{
int n=0;
//第4次修改,将数组中存放的内容改为前后两个元素的差的绝对值
//同时增加一个两个变量来表示前后两个元素
int a[1005];
int first=0,two=0;
int c=0;
int y=0;
cinn;
cinfirst; //输入第一个值
for
{
cintwo; //输入第二个值
a[i]=two-first; //先求差
if(a[i]0)
{
a=-1 * a; //将差放入数组中
}
first = two;
}
//前面写的冒牌排序,这里继续使用,但修改了数组的界限,只有n-1个数
for
{
for
{
//比大小,如果前面的大,就交换位置
if(a[j]a[j+1])
{
c=a[j+1];
a[j+1]=a[j];
a[j]=c;
}
}
}
for
{
if
{
y=1;
break;
}
}
if(y==1)
{
cout"Not jolly";
}
else
{
cout"Jolly";
}
return 0;
}
```
终于OK了。
通过这一次的洛谷练习题说明,程序员必须要冷静,考虑问题要全面,关键的关键是,要仔细读题,仔细读题,仔细读题。
希望他能吸取教训,加油!
失败的经历分享给大家,希望有帮助。
前几期的文章,欢迎浏览转发点赞!!!
1、小学五年级学习两个月C++,拿到CSP-J全国三等奖。
2、信奥赛家长交流。
3、我是如何让上小学的儿子保持学习C++的兴趣。
5、大龄程序员的职业规划与转型问题。
6、中小学生学习编程选择C++还是Python。
7、寒假C++训练课第一天,我布置了一道简单的题目。
8、寒假C++课第二天,学习冒泡排序。