这部分的知识比较基础,但的确是后面学习的深搜和广搜的基础,所以非常重要。为了帮助大家更好的复习,本文依据课上的题目和课后作业题出一期专题。
题目一
请开发一个自上而下的模块化程序,用于完成以下任务
a) 读取两个整数数组,数组的元素未经排序。
b) 将数组元素按递增排序。
c) 将已排序的数组合并。
d) 显示已排序的列表。
使用函数来完成以上每个任务。主函数中只包含函数调用。
代码实现:分成四个函数块,可以留意数组的传递方式。
#include <iostream>
#include <algorithm>
using namespace std;
int s1[1010], s2[1010];
int ans[2020];
void input(int a, int b) {
for (int i = 0; i < a; i++) cin >> s1[i];
for (int i = 0; i < b; i++) cin >> s2[i];
}
void sorts(int x1[], int x2[], int len1, int len2) {
sort(x1, x1 + len1);
sort(x2, x2 + len2);
}
void comb(int x1[], int x2[], int len1, int len2) {
for (int i = 0; i < len1; i++) {
ans[i] = x1[i];
}
for (int i = len1; i < len1 + len2; i++) {
ans[i] = x2[i - len1];
}
}
void print(int len1, int len2) {
for (int i = 0; i < len1 + len2 - 1; i++) cout << ans[i] << " ";
cout << ans[len1 + len2 - 1];
}
int main() {
int x, y;
cin >> x >> y;
input(x, y);
sorts(s1, s2, x, y);
comb(s1, s2, x, y);
print(x, y);
return 0;
}
题目二:二进制补码
输入若干int型整数,输出每个整数的二进制补码。
代码实现:为了展现函数的用法,代码写的比较繁琐。其实补码可以直接通过(n<<i)&1来计算。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int arr[32], temp[32];
void decimalToBinary(int x) {
memset(arr, 0, sizeof(arr));
memset(temp, 0, sizeof(temp));
int cnt = 0;
if (x >= 0) {
while (x > 0) {
temp[cnt] = x % 2;
x /= 2;
cnt++;
}
for (int i = 0; i < cnt; i++) {
arr[31 - i] = temp[i];
}
for (int i = 0; i < 32; i++) cout << arr[i];
cout << endl;
}
else {
x = -x - 1;
while (x > 0) {
temp[cnt] = x % 2;
x /= 2;
cnt++;
}
for (int i = 0; i < cnt; i++) {
arr[31 - i] = temp[i];
}
for (int i = 0; i < 32; i++) cout << 1 - arr[i];
cout << endl;
}
}
int main() {
int n;
while (cin >> n) decimalToBinary(n);
return 0;
}
题目三:密切数判断
任意给定两个正整数,如果这两个数的质因数均相同,那么这两个数称为密切数。例如 6 和 12,其质因数均是 2 和 3;因此,6 和 12 是一对密切数。请判断任意给定的两个正整数是否为一对密切数。若是,输出YES,若不是,输出NO 。
代码实现:考虑分别把两个数的质因数存在s1和s2的数组中,如果数组长度不同,那么不可能是密切数,如果长度相同再分别比较两个数组中的元素是否相同。
#include <iostream>
#include <cmath>
using namespace std;
int s1[1010], s2[1010];
bool isprime(int x) {
for (int i = 2; i <= sqrt(x); i++) {
if (x % i == 0) return false;
}
return true;
}
int zhi(int arr[], int x) {
int cnt = 0;
for (int i = 2; i <= x; i++) {
if (isprime(i) && x % i == 0) {
arr[cnt] = i;
cnt++;
}
}
return cnt;
}
int main() {
int x, y;
char ch;
cin >> x >> ch >> y;
int len1 = zhi(s1, x);
int len2 = zhi(s2, y);
if (len1 != len2) cout << "NO" << endl;
else {
for (int i = 0; i < len1; i++) {
if (s1[i] != s2[i]) {
cout << "NO" << endl;
return 0;
}
}
cout << "YES" << endl;
}
return 0;
}
题目四:生理周期
人生来就有3个生理周期,分别为体力、感情和智力周期,它们的周期长度依次为23天、28天和33天。每一个周期中有一天是高峰。在高峰这天,人会在相应的方面表现出色。因为3个周期的周长不同,所以通常3个周期的高峰不会落在同一天。对于每个人,我们想知道何时3个高峰落在同一天。对于每个周期,给出从当前年份的第一天开始到出现高峰的天数(不一定是第一次高峰出现的时间)。
你的任务是给定一个从当年第一天开始数的天数,输出从给定时间开始(不包括给定时间)下一次3个高峰落在同一天的时间(距给定时间的天数)。例如:给定时间为10,下次出现3个高峰同天的时间是12,则输出2(注意这里不是3)。
代码实现:难点可能在于理解题意,题中的变量比较多,要耐心的捋清楚。我们用day数组记录高峰时间,如果day[i]=3,那么这一天就是三个周期都达到高峰的日子。
#include <iostream>
#include <cstring>
using namespace std;
int day[25000];
void gao(int p, int x) { // p是高峰在一个周期内的天数