小哼的学校要建立一个图书角,老师派小哼去找一些同学做调查,看看同学们都喜欢读哪些书。小哼让每个同学写出一个自己最想读的书的ISBN号(你知道吗?每本书都有唯一的ISBN号,不信话你去找本书翻到背面看看)。当然有一些好书会有很多同学都喜欢,这样就会收集到很多重复的ISBN号。小哼需要去掉其中重复的ISBN号,即每个ISBN号只保留一个,也就说同样的书只买一本(学校真是够抠门的)。然后再把这些ISBN号从小到大排序,小哼将按照排序好的ISBN号去书店去买书。请你协助小哼完成“去重”与“排序”的工作。
输入格式:
输入有2行,第1行为一个正整数,表示有n个同学参与调查(n<=100)。第2行有n个用空格隔开的正整数,为每本图书的ISBN号(假设图书的ISBN号在1~1000之间)。
输出格式:
输出也是2行,第1行为一个正整数k,表示需要买多少本书。第2行为k个用空格隔开的正整数,为从小到大已排好序的需要购买的图书ISBN号。
提示:
改编自全国青少年信息学奥林匹克联赛(NOIP2006)普及组第一题《明明的随机数》。
限制:
每个测试点1秒
样例 1 :
输入:
10
20 40 32 67 40 20 89 300 400 15
输出:
8
15 20 32 40 67 89 300 400
思路:
在这里我们可以有两种思路:
1、先去重,再从小到大排序
2、先从小到大排序,再去重
我们可以用到的方法:桶排序、冒泡排序、快速排序
下面是代码:
桶排序(按照先去重后排序的思路):
/***********************
桶排序
***********************/
#include <stdio.h>
int main()
{
int n,x,num=0;//记录买的书的数目
scanf("%d",&n);
int book[1001]={0};
for(int i=0;i<n;i++)
{
scanf("%d",&x);//书号
if(book[x]==0)//去重的操作,只能有一本
{
num++;
book[x]++;
}
}
printf("%d\n",num);
for(int i=1;i<=1000;i++)
{
if(book[i]==1)
{
printf("%d ",i);//输出被标记的书号
}
}
printf("\n");
return 0;
}
冒泡排序(按照先去重后排序的思路):
/***************************
冒泡排序
***************************/
#include <stdio.h>
int main()
{
int n,j=0,x;//j代表存进数组内书的本数
scanf("%d",&n);
int book[101]={0};
for(int i=0;i<n;i++)
{
int flag =1;//建立一个标记,来判断是否是相同的书号
scanf("%d",&x);
for(int k=0;k<=i;k++)//这个循环的作用是让当前的书号和已存进book数组的书号进行比对,
{
if(book[k]==x)
{
flag=0;
break;
}
}
if(flag==1)//如果没有的话,就存进book数组内
{
book[j]=x;
j++;
}
}
for(int i=0;i<j-1;i++)//冒泡排序
{
for(int k=0;k<j-i-1;k++)//这个地方一定是j-i-1,因为再i=0的时候k最高能取到n-2,如果取到n-1的话后面的book[k+1]就会超出范围
{
if(book[k]>book[k+1])
{
int temp = book[k];
book[k]=book[k+1];
book[k+1]=temp;
}
}
}
printf("%d\n",j);
for(int i=0;i<j;i++)//输出
{
printf("%d ",book[i]);
}
printf("\n");
return 0;
}
快速排序(先排序,后去重)
/***************************
快速排序
***************************/
#include <stdio.h>
void quickSort(int a[],int left,int right)//快速排序
{
if(left >right)
return;
int i=left;
int j=right;
int temp = a[left];
while(i<j)
{
while(a[j]>=temp&&i<j)
{
j--;
}
while(a[i]<=temp&&i<j)
{
i++;
}
if(i<j)
{
int t = a[i];
a[i]=a[j];
a[j]=t;
}
}
a[left]=a[i];
a[i]=temp;
quickSort(a,left,i-1);
quickSort(a,i+1,right);
}
int main()
{
int n,a[101];
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
quickSort(a,0,n-1);
int j=1;
for(int i=1;i<n;i++)//记录总共要买多少本书
{
if(a[i]!=a[i-1])
{
j++;
}
}
printf("%d\n",j);//输出书的本数
printf("%d ",a[0]);//先输出第一个
for(int i=1;i<n;i++)
{
if(a[i]!=a[i-1])//因为相同的书号都是挨着的,所以判断相邻的是否相等,然后把不相等的输出
{
printf("%d ",a[i]);
}
}
printf("\n");
return 0;
}
三种方法的运行结果如下:
输入:
10
20 40 32 67 40 20 89 300 400 15
输出:
8
15 20 32 40 67 89 300 400