之前一直有别的事,好久没更新。一懒下来,acm账号密码都忘了,干脆换oj。
列了几点碰到的困难
1.原来第一个不是数列中的数,而是总个数,这样就简单多了,只要根据其申请动态数组。
2.困惑是否需要逆序排列,从n-1到1排列,后面看了他人处理并无有序要求。
3.还有个小问题,就是辅助数组是否出现过利用difference要减1,因为数组下标是从0开始,最后发现因为自己下标应该是小于num,这样就接收num-1个数字,断点调试加输出语句,才发现这个错误
程序要有出口,不能用while(1)这种不规范的操作写循环,应该将输入作为条件,怪不得oj不ac,以后练习要注意
几点尝试
1.利用辅助数组的时候差点出错,忘记先验证是否改变,appeared每个位置上的元素看做1到n-1,用时间换空间。
2.学会代码的精简不需要引入无用的变量,将表达式当做值理解,作为参数,代码更漂亮。最后的代码进一步精简,输出不是跳跃数的输出统一执行。
3.遇到了想要跳出两层循环的情况,本想尝试goto语句,但是大家普遍不推荐这种可能造成未知情况的操作,就增加一个flag,(额,好像暴露了什么 )判断差值是否都出现过,本来是这么打算的,后来用于判断是否是跳跃数,避免了一个变量的引入。
附ultimate版
#include<iostream>
#include <cmath>
#include <cstring>
using namespace std;
int main()
{
int num;
while(cin>>num){
int *p = new int[num];
for(int i=0;i<num;i++ )
{
cin>>p[i];
}
//the former is difference between elements ,the latter is the label whether appeared
int *difference = new int [num-1];
int *appeared =new int [num-1];
int flag=0;
//zero setting in memory way
memset(appeared, 0, (num-1)*sizeof(appeared));
for(int i=0;i<num-1;i++ )
{
difference[i] = abs(p[i]-p[i+1]);
//check the corresponding label
//out of range or have changed
if(difference[i]>num-1||difference[i]<1||appeared[(difference[i]-1)]==1)
{
flag = 1;
break;
}
else
{
appeared[(difference[i]-1)]=1;
}
}
for(int i=0;i<num-1;i++)
{
//not appear
if (appeared[i] == 0)
{
flag = 1;
break;
}
}
//break uniformly,avoid extra operation
if(flag == 1)
{
cout<<"Not jolly"<<endl;
}
else
{
cout<<"Jolly"<<endl;
}
}
}
找到一篇c版本的,自己写了一篇c++的,对比了一下还是有差距,但我认为只有一个数的情况不需要单独处理,因为已经将辅助数组初始化为0,根本不进变值的循环。附链接:他人的c版本代码
另:尝试了用英文注释,也要好好学学markdown排版博客了。