第五章 数 组¶
第一节 一维数组¶
2034:【例5.1】反序输出¶
提示
题目告诉你有n个数输入,但没有告诉你n是几
烦人不烦人,这里只能用while(cin)
读入的数据,依次存放到数组里
这里面,如何体现“依次”呢?
就是a[idx++] = x,这样的表达
代码
2035:【例5.2】平移数据¶
提示
向左移动,转圈移动
这种收尾相连、转圈移动,是非常常见的编程场景
这个问题简单一点,我们完全可以,for循环下标从2开始,枚举到n
最后输出一个a[1]来解决。
其实,这样做,并没有实现数据存储上的移动,只是利用下标来完成。
当然,我们也可以真的让数据抬抬屁股,向前移动一个位置。
代码
代码2
2036:【例5.3】开关门¶
提示
注意看这句话,“第一个服务员把所有的房间门都打开了”
这句话是有含义的,暗示了,刚开始的时候,
房间的门,是关着的。
1号服务员,把1的倍数,全部处理一遍
2号服务员,把2的倍数,全部处理一遍
i号服务器,把i的倍数,全部处理一遍
最后看,哪些门是打开的
提示2
如何表示门呢?
int door[1010];
默认是0,表示门是关着的
开门就是0->1,关门就是1->0
代码
提示3
仔细观察,最后的输出,你会发现,这些数字,是有规律的
提示4
规律就是,输出的都是完全平方数
为什么?
因为,门刚开始的时候是关着的,做偶数次操作,依然保持关着不变;做奇数次操作,才会变成开着的
谁能操作一个门呢,只有是这个门编号的约数,才能操作
那么,问题就转变为,哪些数,约数的个数,是奇数
我们约数都是成对出现的,只有完全平方数,有一个特殊的完全平方根
代码2
2037:【例5.4】约瑟夫问题¶
提示
约瑟夫问题,是一个经典的数学问题,我听说有相关的数学公式,但我并不会那些
我只会用代码来表达
就是用代码,模拟整个过程。
比较好写的代码,是用一个队列,表达整个数数和出队的过程。
首先,队列,有队头和队尾,从队尾入队,从队头出队,先记住这个逻辑规则。
然后,你就学会了,一个数据结构,队列。
接着,我们来看如何利用队列这个数据结构,模拟这个出队的过程。
我们先设一个变量,来维护123的报数,只要报到m,就恢复成1
然后,队头出队,报数,如果报的不是m,重新入队;如果报的是m,直接输出他的编号,不让其重新入队,相当于踢掉它。
提示2
如何用代码表达队列?
https://www.zqiceberg.com/CPP/STL/#queueint
请访问这个链接,学习队列的基本操作,模仿使用
提示3
这个题目,老师提供多种方法的实现
以此来告诉大家,写代码,有很多种写法
你熟练使用其中一种工具,或者一维数组,或者队列,都可以解决问题
就是实现的过程,有的麻烦饶一点,有的利用数据结构的特点,使得代码简洁易实现。
代码-使用队列
代码-使用一维数组-模拟01
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
bool vis[N];
int n, m;
int cnt;
vector<int> A;
int main(){
cin >> n >> m;
int i = 0;
while (cnt < n) {
int num = 0;
while (num < m - 1) {
while (vis[i]) i = (i + 1) % n;
num++;
i = (i + 1) % n;
}
while (vis[i]) i = (i + 1) % n;
A.push_back(i + 1);
vis[i] = true;
cnt++;
i = (i + 1) % n;
}
for (auto x : A) cout << x << ' ';
return 0;
}
代码-使用一维数组-模拟02
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int a[N];
int n, m, p;
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++) a[i] = i + 1;
int j = 0;
while (n){
j = (j + m - 1) % n;
printf("%d ", a[j]);
for (int i = j + 1; i < n; i++) a[i - 1] = a[i];
n--;
}
puts("");
return 0;
}
代码-使用双链表
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int n, m;
int L[N], R[N];
void remove(int k)
{
L[R[k]] = L[k];
R[L[k]] = R[k];
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++){
R[i] = (i + 1) % n;
L[i] = (i - 1 + n) % n;
}
int k = 0;
for (int i = 0; i < n; i++){
for (int j = 1; j < m; j++) k = R[k];
printf("%d ", k+1);
remove(k);
k = R[k]; //下一个人
}
puts("");
return 0;
}
2038:【例5.5】最大数位置¶
2039:【例5.6】冒泡排序¶
2040:【例5.7】筛选法找质数¶
1102:与指定数字相同的数的个数¶
1103:陶陶摘苹果¶
1104:计算书费¶
1105:数组逆序重存放¶
1106:年龄与疾病¶
1107:校门外的树¶
1108:向量点积计算¶
1109:开关灯¶
1110:查找特定的值¶
1111:不高兴的津津¶
1112:最大值和最小值的差¶
1113:不与最大数相同的数字之和¶
1114:白细胞计数¶
1115:直方图¶
1116:最长平台¶
1117:整数去重¶
1118:铺地毯¶
第二节 二维数组¶
2041:【例5.9】新矩阵¶
2042:【例5.10】稀疏矩阵¶
2043:【例5.11】杨辉三角形¶
2044:【例5.12】回文字串¶
2045:【例5.13】蛇形填数¶
1119:矩阵交换行¶
1120:同行列对角线的格¶
1121:计算矩阵边缘元素之和¶
1122:计算鞍点¶
1123:图像相似度¶
1124:矩阵加法¶
1125:矩阵乘法¶
1126:矩阵转置¶
1127:图像旋转¶
1128:图像模糊处理¶
第三节 字符类型和字符数组¶
2046:【例5.15】替换字母¶
代码
2047:【例5.16】过滤空格¶
提示
过滤多余的空格,并不是把所有空格都删掉
代码
代码02
2048:【例5.18】串排序¶
代码
2049:【例5.19】字符串判等¶
提示
读进来 getline() 空格干掉,统一转成小写
代码
#include <bits/stdc++.h>
using namespace std;
string s1, s2, a, b;
int main(){
getline(cin, s1);
getline(cin, s2);
for (int i = 0, len = s1.size(); i < len; i++)
if (s1[i] != ' ') {
if (s1[i] >= 'A' && s1[i] <= 'Z') s1[i] += 32;
a += s1[i];
}
for (int i = 0, len = s2.size(); i < len; i++)
if (s2[i] != ' ') {
if (s2[i] >= 'A' && s2[i] <= 'Z') s2[i] += 32;
b += s2[i];
}
if (a == b) puts("YES");
else puts("NO");
return 0;
}
2050:【例5.20】字串包含¶
提示
使用.find()函数
代码
1839:【05NOIP提高组】谁拿了最多奖学金¶
代码
#include <iostream>
using namespace std;
int n;
string top;
int maxn = -1;
int sum;
int main(){
cin >> n;
while (n--){
string s;
int pingjun, pingyi;
char ganbu, xibu;
int lunwen;
cin >> s >> pingjun >> pingyi >> ganbu >> xibu >> lunwen;
int now = 0;
if (pingjun > 80 && lunwen >= 1) now += 8000;
if (pingjun > 85 && pingyi > 80) now += 4000;
if (pingjun > 90) now += 2000;
if (pingjun > 85 && xibu == 'Y') now += 1000;
if (pingyi > 80 && ganbu == 'Y') now += 850;
if (now > maxn){
maxn = now;
top = s;
}
sum += now;
}
cout << top << '\n' << maxn << '\n' << sum << '\n';
return 0;
}
1129:统计数字字符个数¶
代码
1130:找第一个只出现一次的字符¶
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 30, M = 1e5 + 10;
int cnt[N]; //0...25
char s[M];
int main(){
scanf("%s", s);
int len = strlen(s);
//O(n)
for (int i = 0; i < len; i++)
cnt[s[i] - 'a']++;
//O(n)
for (int i = 0; i < len; i++)
if (cnt[s[i] - 'a'] == 1){
cout << s[i] << '\n';
return 0;
}
cout << "no" << '\n';
return 0;
}
代码02
1131:基因相关性¶
代码
#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-6;
int main(){
double s;
cin >> s;
string s1, s2;
cin >> s1 >> s2;
int len = (int)s1.size(), cnt = 0;
for (int i = 0; i < len; i++)
if (s1[i] == s2[i]) cnt++;
if (1.0 * cnt / len >= s) cout << "yes" << endl;
else cout << "no" << endl;
return 0;
}
1132:石头剪子布¶
代码
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
string s1, s2;
cin >> n;
while (n--)
{
cin >> s1 >> s2;
int ans;
if (s1 == "Rock" && s2 == "Scissors") ans = 1;
if (s1 == "Rock" && s2 == "Rock") ans = 0;
if (s1 == "Rock" && s2 == "Paper") ans = -1;
if (s1 == "Scissors" && s2 == "Paper") ans = 1;
if (s1 == "Scissors" && s2 == "Scissors") ans = 0;
if (s1 == "Scissors" && s2 == "Rock") ans = -1;
if (s1 == "Paper" && s2 == "Rock") ans = 1;
if (s1 == "Paper" && s2 == "Paper") ans = 0;
if (s1 == "Paper" && s2 == "Scissors") ans = -1;
if (ans == 1) cout << "Player1" << "\n";
else if (ans == 0) cout << "Tie" << "\n";
else cout << "Player2" << "\n";
}
return 0;
}
代码02
#include <bits/stdc++.h>
using namespace std;
string s1, s2;
int main(){
int n;
cin >> n;
while (n--){
int a = 0, b = 0;
cin >> s1 >> s2;
if (s1[0] == 'R'){
if (s2[0] == 'S') a++;
else if (s2[0] == 'P') b++;
}
if (s1[0] == 'P'){
if (s2[0] == 'R') a++;
else if (s2[0] == 'S') b++;
}
if (s1[0] == 'S'){
if (s2[0] == 'P') a++;
else if (s2[0] == 'R') b++;
}
if (a == b) cout << "Tie" << '\n';
if (a > b) cout << "Player1" << '\n';
if (a < b) cout << "Player2" << '\n';
}
return 0;
}
1133:输出亲朋字符串¶
代码
1134:合法C标识符查¶
代码
#include <bits/stdc++.h>
using namespace std;
string s;
int cnt;
int main(){
cin >> s;
if(s[0]>='0'&&s[0]<='9') cnt++;
for(int i=0,len=s.size();i<len;i++) {
if (!((s[i]>='0'&&s[i]<='9')||(s[i]>='a'&&s[i]<='z')||(s[i]>='A'&&s[i]<='Z')||s[i]=='_')) cnt++;
if (i == 0 && (s[i] >= '0' && s[i] <= '9')) cnt++;
}
if(cnt >= 1) cout <<"no";
else cout <<"yes";
return 0;
}
1135:配对碱基链¶
1136:密码翻译¶
代码
#include <bits/stdc++.h>
using namespace std;
string s;
int main(){
getline(cin, s);
for (int i = 0, len = s.size(); i < len; i++) {
if ((s[i] >= 'a' && s[i] <= 'y') || (s[i] >= 'A' && s[i] <= 'Y'))
s[i]++;
else if (s[i] == 'z') s[i] = 'a';
else if (s[i] == 'Z') s[i] = 'A';
}
cout << s << '\n';
return 0;
}
代码02
#include <bits/stdc++.h>
using namespace std;
int main(){
string s;
getline(cin, s);
for (int i = 0, len = (int)s.size(); i < len; i++)
{
if (s[i] >= 'a' && s[i] <= 'z') s[i] = 'a' + ((s[i] - 'a') + 1) % 26;
if (s[i] >= 'A' && s[i] <= 'Z') s[i] = 'A' + ((s[i] - 'A') + 1) % 26;
}
cout << s << endl;
return 0;
}
1137:加密的病历单¶
代码
#include<bits/stdc++.h>
using namespace std;
string s;
int main(){
cin >> s;
int len = s.size();
for (int i = 0; i < len; i++){
char c = s[i];
if (c >= 'a' && c <= 'z'){
s[i] = 'a' + (c - 'a' + 3) % 26;
s[i] -= 'a' - 'A';
}
else{
s[i] = 'A' + (c - 'A' + 3) % 26;
s[i] += 'a' - 'A';
}
}
reverse(s.begin(), s.end());
cout << s << '\n';
return 0;
}
1138:将字符串中的小写字母转换成大写字母¶
代码
1139:整理药名¶
代码
1140:验证子串¶
提示
.find() 函数
代码
#include <bits/stdc++.h>
using namespace std;
int main(){
string s, s2;
cin >> s >> s2;
if (s2.size() < s.size()){
if(s.find(s2) != string::npos) cout << s2 << ' ' << "is substring of" << ' ' << s;
else cout << "No substring" << '\n';
}
else{
if(s2.find(s) != string::npos) cout << s << ' ' << "is substring of" << ' ' << s2;
else cout << "No substring" << '\n';
}
return 0;
}
1141:删除单词后缀¶
代码
#include <bits/stdc++.h>
using namespace std;
int main(){
string s;
cin >> s;
int len = s.size();
if (s[len - 2] == 'e' && s[len - 1] == 'r') s.erase(len - 2);
if (s[len - 2] == 'l' && s[len - 1] == 'y') s.erase(len - 2);
if (s[len - 3] == 'i' && s[len - 2] == 'n' && s[len - 1] == 'g') s.erase(len - 3);
cout << s << endl;
return 0;
}
代码02
1142:单词的长度¶
代码
#include <bits/stdc++.h>
using namespace std;
int main(){
string s;
getline(cin, s);
bool flag = false;
for (int i = 0, len = s.size(); i < len; i++) {
while (s[i] == ' ') i++;
if (flag) printf(",");
flag = true;
int j = i;
int cnt = 0;
while (j < len && s[j] != ' ') j++;
printf("%d", j - i);
i = j - 1;
}
return 0;
}
代码02
1143:最长最短单词¶
代码
#include <bits/stdc++.h>
using namespace std;
int main(){
string s;
getline(cin, s);
int maxn = -1, minn = 110;
string maxt, mint;
for (int i = 0, len = s.size(); i < len; i++) {
if (s[i] == ' ' || s[i] == ',') continue;
string t;
int j = i;
while (j < len && s[j] != ' ' && s[j] != ',') t += s[j++];
if (j - i > maxn) maxn = j - i, maxt = t;
if (j - i < minn) minn = j - i, mint = t;
// j = i
i = j;
}
cout << maxt << endl << mint << endl;
return 0;
}
1144:单词翻转¶
代码
#include <bits/stdc++.h>
using namespace std;
string s;
int main(){
getline(cin, s);
for (int i = 0, len = s.size(); i < len; i++){
if (s[i] == ' '){
cout << s[i];
continue;
}
int j = i;
string temp;
while (j < len && s[j] != ' ') temp += s[j++];
reverse(temp.begin(), temp.end());
cout << temp;
i = j - 1;
}
return 0;
}
1145:字符串p型编码¶
代码
1146:判断字符串是否为回文¶
代码
代码02
1147:最高分数的学生姓名¶
代码
1148:连续出现的字符¶
代码
#include <bits/stdc++.h>
using namespace std;
int main(){
int k;
string s;
cin >> k >> s;
bool flag = false;
for (int i = 0, len = (int)s.size(); i < len; i++) {
int j = i;
while (j < len && s[j] == s[i]) j++;
int cnt = j - i;
if (cnt >= k) {
flag = true;
cout << s[i] << endl;
break;
}
}
if (!flag) cout << "No" << endl;
return 0;
}
1149:最长单词2¶
代码
#include <bits/stdc++.h>
using namespace std;
int main(){
string s;
getline(cin, s);
int maxn = -1;
string ans;
for (int i = 0, len = (int)s.size(); i < len - 1; i++) {
int j = i;
string temp;
while (j < len - 1 && s[j] != ' ') {
temp += s[j];
j++;
}
if (j - i > maxn) {
maxn = j - i;
ans = temp;
}
}
cout << ans << endl;
return 0;
}
代码02
#include<bits/stdc++.h>
using namespace std;
string s;
string ans;
int maxn;
int main(){
while (cin >> s){
if (s[s.size() - 1] == '.'){
if (s.size() - 1 > maxn){
maxn = s.size() - 1;
s.pop_back();
ans = s;
}
}else{
if (s.size() > maxn){
maxn = s.size();
ans = s;
}
}
}
cout << ans << '\n';
return 0;
}