跳转至

第五章 数 组

第一节 一维数组

2034:【例5.1】反序输出

提示

题目告诉你有n个数输入,但没有告诉你n是几

烦人不烦人,这里只能用while(cin)

读入的数据,依次存放到数组里

这里面,如何体现“依次”呢?

就是a[idx++] = x,这样的表达

代码
#include <bits/stdc++.h>

using namespace std;

int a[110], x, idx;

int main(){
    while (cin >> a[idx++]){

    }

    // 要注意思考,最后一个数的下标,到底是多少
    idx--;
    for (int i = idx - 1; i >= 0; i--) cout << a[i] << ' ';  
    puts("");

    return 0;
}

2035:【例5.2】平移数据

提示

向左移动,转圈移动

这种收尾相连、转圈移动,是非常常见的编程场景

这个问题简单一点,我们完全可以,for循环下标从2开始,枚举到n

最后输出一个a[1]来解决。

其实,这样做,并没有实现数据存储上的移动,只是利用下标来完成。

当然,我们也可以真的让数据抬抬屁股,向前移动一个位置。

代码
#include<iostream>

using namespace std;

const int N = 1010;

int a[N], n;

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];

    for (int i = 2; i <= n; i++) cout << a[i] << ' ';
    cout << a[1];
    puts("");

    return 0;
}
代码2
#include<iostream>

using namespace std;

const int N = 1010;

int a[N], n;

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];

    int t = a[1];
    for (int i = 1; i < n; i++) a[i] = a[i + 1];
    a[n] = t;

    for (int i = 1; i <= n; i++) cout << a[i] << ' ';

    return 0;
}

2036:【例5.3】开关门

请先反复读题,不要着急
提示

注意看这句话,“第一个服务员把所有的房间门都打开了”

这句话是有含义的,暗示了,刚开始的时候,

房间的门,是关着的。

1号服务员,把1的倍数,全部处理一遍

2号服务员,把2的倍数,全部处理一遍

i号服务器,把i的倍数,全部处理一遍

最后看,哪些门是打开的

提示2

如何表示门呢?

int door[1010];

默认是0,表示门是关着的

开门就是0->1,关门就是1->0

代码
#include <bits/stdc++.h>

using namespace std;

bool door[1010]; // false代表关

int main(){
    int n;
    cin >> n;

    for (int i = 1; i <= n; i++)
        for (int j = i; j <= n; j += i)
            door[j] = !door[j];

    for (int i = 1; i <= n; i++)
        if (door[i]) cout << i << ' ';
    puts("");


    return 0;
}
提示3

仔细观察,最后的输出,你会发现,这些数字,是有规律的

提示4

规律就是,输出的都是完全平方数

为什么?

因为,门刚开始的时候是关着的,做偶数次操作,依然保持关着不变;做奇数次操作,才会变成开着的

谁能操作一个门呢,只有是这个门编号的约数,才能操作

那么,问题就转变为,哪些数,约数的个数,是奇数

我们约数都是成对出现的,只有完全平方数,有一个特殊的完全平方根

代码2
#include <bits/stdc++.h>

using namespace std;

const int N = 1010;

int n;

int main(){
    cin >> n;

    for (int i = 1; i * i <= n; i++) cout << i * i << ' ';
    puts("");

    return 0;
}

2037:【例5.4】约瑟夫问题

这道题目,拿到手

你先把样例,在纸上,模拟一遍

8 5

5 2 8 7 1 4 6 3
提示

约瑟夫问题,是一个经典的数学问题,我听说有相关的数学公式,但我并不会那些

我只会用代码来表达

就是用代码,模拟整个过程。

比较好写的代码,是用一个队列,表达整个数数和出队的过程。

首先,队列,有队头和队尾,从队尾入队,从队头出队,先记住这个逻辑规则。

然后,你就学会了,一个数据结构,队列。

接着,我们来看如何利用队列这个数据结构,模拟这个出队的过程。

我们先设一个变量,来维护123的报数,只要报到m,就恢复成1

然后,队头出队,报数,如果报的不是m,重新入队;如果报的是m,直接输出他的编号,不让其重新入队,相当于踢掉它。

提示2

如何用代码表达队列?

https://www.zqiceberg.com/CPP/STL/#queueint

请访问这个链接,学习队列的基本操作,模仿使用

提示3

这个题目,老师提供多种方法的实现

以此来告诉大家,写代码,有很多种写法

你熟练使用其中一种工具,或者一维数组,或者队列,都可以解决问题

就是实现的过程,有的麻烦饶一点,有的利用数据结构的特点,使得代码简洁易实现。

代码-使用队列
#include <bits/stdc++.h>

using namespace std;

int main()
{
    int n, m;
    cin >> n >> m;

    queue<int> q;
    for (int i = 1; i <= n; i++) q.push(i);

    int k = 0;
    while (!q.empty()){
        k++;

        int t = q.front(); q.pop();

        if (k == m){
            k = 0;
            printf("%d ", t);
            continue;
        }

        q.push(t);
    }
    puts("");

    return 0;
}
代码-使用一维数组-模拟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】替换字母

代码
#include <bits/stdc++.h>

using namespace std;

const int N = 210;

string s;
char a, b;

int main(){
    getline(cin, s);
    cin >> a >> b;

    for (int i = 0, len = s.size(); i < len; i++)
        if (s[i] == a) s[i] = b;

    cout << s << '\n';

    return 0;
}

2047:【例5.16】过滤空格

提示

过滤多余的空格,并不是把所有空格都删掉

代码
#include <bits/stdc++.h>

using namespace std;

int main(){
    string s;
    getline(cin, s);

    for (int i = 0, len = s.size(); i < len; i++) {
        if (i && s[i] == ' ' && s[i - 1] == ' ') continue;
        cout << s[i];
    }

    return 0;
}
代码02
#include <bits/stdc++.h>

using namespace std;

string s;

int main(){
    while (cin >> s) cout << s << ' ';
    puts("");

    return 0;
}

2048:【例5.18】串排序

代码
#include <bits/stdc++.h>

using namespace std;

string s[25];
int n;

int main(){
    cin >> n;
    for (int i = 0; i < n; i++) cin >> s[i];

    sort(s, s + n);

    for (int i = 0; i < n; i++) cout << s[i] << '\n';

    return 0;
}

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()函数

代码
#include <bits/stdc++.h>
using namespace std;

int main(){
    string a, b;
    cin >> a >> b;

    string a2 = a + a;
    string b2 = b + b;

    if (a2.find(b) != string::npos || b2.find(a) != string::npos) {
        cout << "true";
    } else {
        cout << "false";
    }

    return 0;
}

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:统计数字字符个数

代码
#include <bits/stdc++.h>

using namespace std;

int main(){
    string s;
    getline(cin, s);

    int cnt = 0;
    for (int i = 0, len = (int)s.size(); i < len; i++)
        if (s[i] >= '0' && s[i] <= '9')
            cnt++;

    cout << cnt << endl;

    return 0;
}

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
#include <iostream>

using namespace std;

int main(){
    string s;
    cin >> s;

    for (int i = 0, len = s.size(); i < len; i++) {
        bool flag = false;
        for (int j = 0; j < len; j++)
            if (s[j] == s[i] && i != j) {flag = true; break;}

        if (!flag) {cout << s[i]; return 0;}
    }

    cout << "no";

    return 0;
}

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:输出亲朋字符串

代码
#include <iostream>
#include <cstdio>
#include <stdio.h>
using namespace std;
string a,s;
int main(){
    cin >> a;
    for(int i = 0, len = a.size(); i < len; i++){
        char c;
        if (i < len - 1) c = a[i] + a[i + 1];
        else c = a[i] + a[0];

        s+=c;
    }

    cout<<s;

    return 0;
}

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:将字符串中的小写字母转换成大写字母

代码
#include <bits/stdc++.h>

using namespace std;

int main(){
    string s;
    //cin >> s;
    getline(cin, s);

    for (int i = 0, len = s.size(); i < len; i++)
        if (s[i] >= 'a' && s[i] <= 'z') s[i] -= 32;

    cout << s << endl;

    return 0;
}

1139:整理药名

代码
#include <iostream>

using namespace std;

int n;
string s;

int main(){
    cin >> n;
    while (n--){
        cin >> s;

        if (s[0] >= 'a' && s[0] <= 'z') s[0] -= 32;
        for (int i = 1, len = s.size(); i < len; i++)
            if (s[i] >= 'A' && s[i] <= 'Z') s[i] += 32;

        cout << s << '\n';  
    }

    return 0;
}

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
#include<iostream>

using namespace std;

int main(){
    string s;
    cin >> s;

    s += ' ';
    if (s.find("er ") != -1) s.erase(s.find("er "));
    if (s.find("ly ") != -1) s.erase(s.find("ly "));
    if (s.find("ing ") != -1) s.erase(s.find("ing "));

    cout << s << '\n';

    return 0;
}

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
#include <bits/stdc++.h>

using namespace std;

int main(){
    //freopen("1.in", "r", stdin);

    string s;
    bool flag = false;
    while (cin >> s){
        if (flag) cout << ',';
        flag = true;

        int len = s.size();
        cout << len;
    }
    puts("");

    return 0;
}

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型编码

代码
#include <bits/stdc++.h>

using namespace std;

string s;

int main(){
    cin >> s;
    for (int i = 0, len = s.size(); i < len; i++){
        int cnt = 0, j = i;
        while (j < len && s[j] == s[i]) cnt++, j++;

        cout << cnt << s[i];
        i = j - 1;
    }

    return 0;
}

1146:判断字符串是否为回文

代码
#include <bits/stdc++.h>

using namespace std;

int main(){
    string s;
    cin >> s;
    int l = 0, r = s.size() - 1;
    while (l < r){
        if (s[l] == s[r]) l++, r--;
        else break;
    }

    if (l < r) cout << "no" << '\n';
    else cout << "yes" << '\n';

    return 0;
}
代码02
#include <bits/stdc++.h>

using namespace std;

int main(){
    string s;
    cin >> s;

    string s2 = s;
    reverse(s.begin(), s.end());

    if (s == s2) cout << "yes" << '\n';
    else cout << "no" << '\n';

    return 0;
}

1147:最高分数的学生姓名

代码
#include <bits/stdc++.h>

using namespace std;

int main(){
    int n;
    cin >> n;

    int maxn = -1;
    string ans;

    while (n--) {
        int x;
        string s;
        cin >> x >> s;

        if (x > maxn)  {
            maxn = x;
            ans = s;
        }
    }

    cout << ans << endl;

    return 0;
}

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;
}
代码03
#include <bits/stdc++.h>

using namespace std;

string ret, t;

int main(){
    string s;
    getline(cin, s);

    for (int i = 0, len = s.size(); i < len; i++){
        if (s[i] != ' ' && s[i] != '.') t += s[i];
        else{
            if (t.size() > ret.size()) ret = t;
            t.clear();
        }
    }

    cout << ret << '\n';

    return 0;
}