题目
洛谷 P1059 [NOIP2006 普及组] 明明的随机数
题目描述
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了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
代码
-
首先通过
scanf
函数从标准输入中获取一个整数n
,该整数表示接下来要输入的整数个数。 -
声明一个大小为
n
的整型数组a
,并通过循环将n
个整数依次存储到数组a
中。 -
使用冒泡排序算法对数组
a
进行升序排序。冒泡排序的基本思想是,从第一个元素开始,逐一比较相邻的两个元素,若前者比后者大,则交换它们的位置。通过多次遍历,将最大的元素冒泡到最后的位置。通过这样的遍历和交换过程,数组a
中的元素会逐渐有序。 -
遍历数组
a
,如果当前元素与后一个元素相等,则说明存在重复元素,需要将后面的元素往前移动,并相应地将数组的长度减1。 -
输出去重后数组的长度
sum
和去重后的数组内容。
cpp
#include <stdio.h> // 包含标准输入输出库头文件
int main() { // 主函数
int n; // 声明一个整型变量 n
scanf("%d", &n); // 从标准输入中读取一个整数并存储到变量 n 中
int a[n]; // 声明一个大小为 n 的整型数组 a,这是一个变长数组(VLA)
for (int i = 0; i < n; i++) { // 循环读取 n 个整数到数组 a 中
scanf("%d", &a[i]); // 读取一个整数存储到数组 a 中
}
int t; // 声明一个临时整型变量 t
int sum = n; // 声明一个整型变量 sum 并初始化为 n
for (int i = 0; i < n; i++) { // 外层循环,控制比较轮次
for (int j = 0; j < (n - 1) - i; j++) { // 内层循环,控制每轮比较次数
if (a[j] > a[j + 1]) { // 如果前面的数大于后面的数
t = a[j]; // 交换两个数的值
a[j] = a[j + 1];
a[j + 1] = t;
}
}
}
for (int i = 0; i < sum; i++) { // 遍历数组去除重复元素
if (a[i] == a[i + 1]) { // 如果当前元素等于后面一个元素
for (int k = i + 1; k < sum; k++) { // 从i+1位置开始往后遍历
a[k] = a[k + 1]; // 后面的元素覆盖当前元素
}
sum--; // 数组长度减一
i--; // 因为覆盖了当前元素,所以需要回退一个位置
}
}
printf("%d\n", sum); // 输出去重后数组的长度
for (int i = 0; i < sum; i++) { // 输出去重后的数组内容
printf("%d ", a[i]);
}
return 0; // 返回0,表示程序正常结束
}
-
头文件和主函数定义:
#include <stdio.h> // 包含标准输入输出库头文件
int main() { // 主函数
-
变量定义和输入:
int n; // 声明一个整型变量 n scanf("%d", &n); // 从标准输入中读取一个整数并存储到变量 n 中 int a[n]; // 声明一个大小为 n 的整型数组 a,这是一个变长数组(VLA) for (int i = 0; i < n; i++) { // 循环读取 n 个整数到数组 a 中 scanf("%d", &a[i]); // 读取一个整数存储到数组 a 中 }
-
冒泡排序:
int t; // 声明一个临时整型变量 t for (int i = 0; i < n; i++) { // 外层循环,控制比较轮次 for (int j = 0; j < (n - 1) - i; j++) { // 内层循环,控制每轮比较次数 if (a[j] > a[j + 1]) { // 如果前面的数大于后面的数 t = a[j]; // 交换两个数的值 a[j] = a[j + 1]; a[j + 1] = t; } } }
-
去重:
int sum = n; // 声明一个整型变量 sum 并初始化为 n for (int i = 0; i < sum; i++) { // 遍历数组去除重复元素 if (a[i] == a[i + 1]) { // 如果当前元素等于后面一个元素 for (int k = i + 1; k < sum; k++) { // 从 i+1 位置开始往后遍历 a[k] = a[k + 1]; // 后面的元素覆盖当前元素 } sum--; // 数组长度减一 i--; // 因为覆盖了当前元素,所以需要回退一个位置 } }
-
输出结果:
printf("%d\n", sum); // 输出去重后数组的长度 for (int i = 0; i < sum; i++) { // 输出去重后的数组内容 printf("%d ", a[i]); }
-
返回:
return 0; // 返回0,表示程序正常结束
}