题目如下
总时间限制: 1000ms
内存限制: 65536kB
描述
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。 然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。 请你协助明明完成“去重”与“排序”的工作。
输入
有2行,第1行为1个正整数,表示所生成的随机数的个数:N;
第2行有N个用空格隔开的正整数,为所产生的随机数。
输出
也是2行,第1行为1个正整数M,表示不相同的随机数的个数。 第2行为M个用空格隔开的正整数,为从小到大排好序的不相同的随机数。
样例输入
10 20 40 32 67 40 20 89 300 400 15
样例输出
8 15 20 32 40 67 89 300 400
我的思路:
排序-->去重-->计数并输出
(这是一个常规思路,容易想到。 就是根据题目要求,实现每一个小环节)
int main()
{
int a[100];
int n, i, j,t,cnt=0;
//输入
scanf("%d",&n);
for (i = 0;i < n; i++){
scanf("%d", a + i);
}
//将所有随机数排序 这里采用的是冒泡排序
for (i = 0;i < n; i++) {
for (j = 0;j < n - i - 1;j++) {
if (a[j] > a[j + 1]) {
t = a[j];
a[j] = a[j + 1];
a[j + 1] = t;
}
}
}
//计算去重后随机数的个数为cnt
for (i = 0;i < n;i++) {
if (a[i] == a[i + 1]) {}
else cnt++;
}
printf("%d\n", cnt);//输出去重后随机数的个数
//去重输出随机数
for (i = 0;i < n;i++) {
if (a[i] == a[i + 1])//如果有相同的数,就用continue跳过输出,使相同的随机数只被输出一次
continue;
else printf("%d ", a[i]);
}
return 0;
}
这里,因为题目要求只需要输出去重的数字就行了,所以就简单地用了一个if-else语句加continue,使每个数只被输出一次。
for (i = 0;i < n;i++) {
if (a[i] == a[i + 1])
continue;
else printf("%d ", a[i]);
}
如果是要删除一个数组中重复的数字,就需要用几个循环先判断有没有重复的数,若有重复数字,就要依次将数组大小减一,也就是删掉重复元素(和覆盖的意思差不多)
网上的解法:
int main(){
int N,a[1001]={0},t,i;
int count=0;
scanf("%d",&N);
for(i=0;i<N;i++){
scanf("%d",&t);
if(a[t]==0){
a[t]=t;
count++;
}
}
printf("%d\n",count);
for(i=0;i<1001;i++){
if(a[i]!=0)
printf("%d ",a[i]);
}
return 0;
}
第一眼:好简洁啊!
再看:太妙了吧!
下面说说自己的理解吧(自己理一遍),如果对你也有帮助就更好啦!(O(∩_∩)O)
首先,和普通解法不一样的是这个数组a, 作者将数组a的大小初始化为1001,同时将每个元素赋值为0。
这是有用处的,妙也就是在这里。
题目不是说,生成的随机数大小在1到1000嘛,显然,设置1001大小的数组a是为了后续将数组元素下标与随机数的值联系起来。
看!接下来的随机数输入部分。
int N,a[1001]={0},t,i;
a[t]=t; 就是将一个随机数 t 填入了数组a中下标为t的位置。
前面的 if(a[t]==0) 是用来判断这个下标为t的位置有没有被 “填入”过,如果被 “填入”过,就不会被二次“填入”。
-----这样,有了if判断就在输入的时候同时解决了去重的环节 !!
count++; 计数。
for(i=0;i<N;i++){
scanf("%d",&t);
if(a[t]==0){
a[t]=t;
count++;
}
}
然后,遍历数组a输出被填入的随机数
因为输入时是 数组下标=随机数的值,所以遍历输出不为0的a数组元素就自然是按从小到大的顺序输出的了!
-----这样,就在输出的时候解决了排序的环节!!
for(i=0;i<1001;i++){
if(a[i]!=0)
printf("%d ",a[i]);
}
总结一下
这个解法很巧妙地利用了数组的特点。
这给我们的启示是:有时候,合理利用数组的特点可以简化很多步骤。
在以后可以多去尝试探索、思考这样的优化解法。
由此想到的另一个利用数组特点优化解法的例子是 “统计每个数字出现的数字”
建立一个数组a
出现1,则a[1]++;
出现7,则a[7]++;
……
这样就用a[1]、a[7]来计数1和7出现的次数,就省去了一些繁复的变量定义,而且清晰直观。
以上只是自己在学c过程中的记录,希望也能帮到你。