一、 明明的随机数
题目描述
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了 N 个 1 到 1000 之间的随机整数 ,对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。
输入格式
输入有两行,第 1 行为 1 个正整数,表示所生成的随机数的个数 N。
第 2 行有 N 个用空格隔开的正整数,为所产生的随机数。
输出格式
输出也是两行,第 1 行为 1 个正整数 M,表示不相同的随机数的个数。
第 2 行为 M 个用空格隔开的正整数,为从小到大排好序的不相同的随机数。
样例 #1
样例输入 #1
10
20 40 32 67 40 20 89 300 400 15
样例输出 #1
8
15 20 32 40 67 89 300 400
我的答案
#include <iostream>
#include <algorithm>
using namespace std;
void removeDuplicates(int arr[], int& n);//必须在main函数前声明
int main() {
int N;
cin >> N;
int* num = new int[N]; // 动态分配内存,因为是动态数组,元素数目会改变
for (int i = 0; i < N; i++) {
cin >> num[i];
}
removeDuplicates(num, N); // 数组排序,去重
cout << N << endl;
for (int i = 0; i < N; i++) {
cout << num[i] << ' ';
}
cout << endl;
delete[] num; // 释放内存
system("pause");
}
void removeDuplicates(int arr[], int& n) { // 定义
sort(arr, arr + n); // 对数组排序
int j = 0;
for (int i = 1; i < n; i++) {
if (arr[i] != arr[j]) { // 如果当前元素和前一个元素不相等
arr[++j] = arr[i]; // 把当前元素放到数组中
}
}
n = j + 1; // 更新数组长度
}
其他方法
方法一(set容器)
使用 set
容器来实现去重和排序。set
自动会将元素从小到大排序,并保证集合中的元素不重复。需要注意的是,这里使用了范围 for 循环来遍历集合,需要使用 auto&
来对集合中的元素进行引用,否则会出现编译错误。
#include <iostream>
#include <set>
using namespace std;
int main() {
int N;
cin >> N;
set<int> s;
for (int i = 0; i < N; i++) {
int x;
cin >> x;
s.insert(x); // 插入元素x到集合s中
}
// 输出去重后的元素
cout << s.size() << endl;
for (auto& x : s) {
cout << x << ' ';
}
cout << endl;
return 0;
}
方法二、使用数组实现
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int N;
cin >> N;
int a[N];
for (int i = 0; i < N; i++) {
cin >> a[i];
}
sort(a, a + N); // 对数组进行排序
int n = unique(a, a + N) - a; // unique 函数返回不重复元素的末尾位置,我们使用指针偏移来计算不重复元素的个数
// 输出去重后的元素
cout << n << endl;
for (int i = 0; i < n; i++) {
cout << a[i] << ' ';
}
cout << endl;
return 0;
}
需要注意的是,unique
函数会返回不重复元素的末尾位置,我们需要使用指针偏移来计算不重复元素的个数。例如,输入数组arr[]={1,2,4,4,5,6,6}
,返回数组arr[]={1,2,4,5,6}
。缺点是只能去除相邻重复项,因此必须先对数组进行排序才能实现完全去重。
与方法一相比,方法二不需要额外空间去存储去重后的元素,但是需要对输入的数组进行排序,时间复杂度较高。
方法三:哈希表
使用 unordered_set
哈希表来实现去重。如果输入的元素不在哈希表中,我们将其插入到哈希表中,并将其插入到 vector
中。最后,我们对 vector
中的元素进行排序,并输出去重后的元素。使用哈希表的优点是插入和查找的时间复杂度较低,缺点是需要额外的空间来存储哈希表。
#include <iostream>
#include <unordered_set>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int N;
cin >> N;
unordered_set<int> s;
vector<int> v;
for (int i = 0; i < N; i++) {
int x;
cin >> x;
if (s.find(x) == s.end()) { // 如果 x 不在哈希表中
s.insert(x); // 插入元素到哈希表中
v.push_back(x); // 插入元素到 vector 中
}
}
sort(v.begin(), v.end()); // 对 vector 中的元素进行排序
// 输出去重后的元素
cout << v.size() << endl;
for (auto& x : v) {
cout << x << ' ';
}
cout << endl;
return 0;
}
二、 质因数分解
题目描述
已知正整数 n 是两个不同的质数的乘积,试求出两者中较大的那个质数。
输入格式
输入一个正整数 n。
输出格式
输出一个正整数 p,即较大的那个质数。
样例 #1
样例输入 #1
21
样例输出 #1
7
提示
我的答案
#include <iostream>
using namespace std;
int main()
{
int n, f1, f2;
cin >> n;
for (int i = 2; i <= n / 2; i++)
{
if (n % i == 0)
{
f2 = n / i;
break;
}
}
cout << f2;
return 0;
}
其实这里有个隐藏条件:正整数 n 是两个不同的质数的乘积,所以求出来的因子必定是质数。如果真要考虑因子是否为质数,方法如下:
#include <iostream>
using namespace std;
bool is_prime(int x) // 判断一个数是否为质数
{
if (x < 2)
return false;
for (int i = 2; i * i < x; i++)
{
if (x % i == 0)
{
return false;
}
}
return true;
}
int main()
{
int n;
cin >> n;
int factor;
for (int i = 2; i*i<=n; i++)
{
if (is_prime(i) && n % i == 0)
{
factor = n / i;
break;
}
}
cout<<factor;
return 0;
}
当n较大时,程序的运行时间会比较长。我们可以进一步优化时间复杂度。注意到n是两个质数的乘积,因此其中一个质数一定不超过 ,我们只需要从 开始往下遍历即可,这样可以减小时间复杂度。
for (int i = n / 2; i >= 2; i--) {
if (n % i == 0 && is_prime(i))
{
factor = n/i;
break;
}
}
三、 不高兴的津津
题目描述
津津上初中了。妈妈认为津津应该更加用功学习,所以津津除了上学之外,还要参加妈妈为她报名的各科复习班。另外每周妈妈还会送她去学习朗诵、舞蹈和钢琴。但是津津如果一天上课超过八个小时就会不高兴,而且上得越久就会越不高兴。假设津津不会因为其它事不高兴,并且她的不高兴不会持续到第二天。请你帮忙检查一下津津下周的日程安排,看看下周她会不会不高兴;如果会的话,哪天最不高兴。
输入格式
输入包括 7 行数据,分别表示周一到周日的日程安排。每行包括两个小于 10 的非负整数,用空格隔开,分别表示津津在学校上课的时间和妈妈安排她上课的时间。
输出格式
一个数字。如果不会不高兴则输出 0,如果会则输出最不高兴的是周几(用 1, 2, 3, 4, 5, 6, 7 分别表示周一,周二,周三,周四,周五,周六,周日)。如果有两天或两天以上不高兴的程度相当,则输出时间最靠前的一天。
样例 #1
样例输入 #1
5 3
6 2
7 2
5 3
5 4
0 4
0 6
样例输出 #1
3
我的答案
#include <iostream>
using namespace std;
int main()
{
int a[7], b[7], c[7], n;
for (int i = 0; i < 7; i++)
{
cin >> a[i] >> b[i];
c[i] = a[i] + b[i];
}
int max = c[0];
for (int i = 1; i < 7; i++)
{
if (max < c[i])
{
max = c[i];
n = i + 1; // 易错
}
}
cout << n;
return 0;
}