给定一个只包含大写字母 A
− Z
的字符串,找到相邻两个元音字母之间间隔最大的距离。
注:元音字母为 AEIOU
思路:记录上一个元音字母的位置last
,以及当前访问的元音字母的位置i
,计算最大距离判断是否更新ans的结果。如此循环
//版本1:逻辑混乱
bool check(char c) {if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') return true;return false;
}int func(string str) {int index[2];int maxlen = 0;int flag = 0;for (int i = 0; i < str.length(); ++i) {if (flag && check(str[i])) {index[1] = i;int newlen = index[1] - index[0];if (newlen > maxlen) maxlen = newlen; index[0] = index[1];}if (!flag && check(str[i])) {//第1个元音字母index[0] = i;flag = 1;}}return maxlen;
}//版本2:对首个元音字母的处理 进行逻辑优化
bool check(char c) {if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') return true;return false;
}int func(string str) {int last = -1;int maxlen = 0;for (int i = 0; i < str.length(); ++i) {if (check(str[i])) {if (last == -1) last = i;else {maxlen = max(maxlen, i - last);last = i;}}}return maxlen;
}//版本3:优化部分细节 集成check函数
int func(string str) {int ans = 0;int last = -1;for (int i = 0; str[i]; ++i) {if (str[i] == 'A' || str[i] == 'E' || str[i] == 'I' || str[i] == 'O' || str[i] == 'U') {if (last == -1) last = i;else {ans = max(ans, i - last);last = i;}}}return ans;
}
国际乒联前主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及。
其中 11 分制改革引起了很大的争议,有一部分球员因为无法适应新规则只能选择退役。华华就是其中一位,他退役之后走上了乒乓球研究工作,意图弄明白 11 分制和 21 分制对选手的不同影响。在开展他的研究之前,他首先需要对他多年比赛的统计数据进行一些分析,所以需要你的帮忙。
华华通过以下方式进行分析,首先将比赛每个球的胜负列成一张表,然后分别计算在 11 分制和 21 分制下,双方的比赛结果(截至记录末尾)。
比如现在有这么一份记录,(其中 W 表示华华获得一分,L 表示华华对手获得一分):
WWWWWWWWWWWWWWWWWWWWWWLW
你的程序就是要对于一系列比赛信息的输入(WL形式),输出正确的结果。
输入:每个输入文件包含若干行字符串,字符串有大写的 W、L 和 E 组成。其中 E 表示比赛信息结束,程序应该忽略 E 之后的所有内容。
WWWWWWWWWWWWWWWWWWWW
WWLWE
输出:输出由两部分组成,每部分有若干行,每一行对应一局比赛的比分(按比赛信息输入顺序)。其中第一部分是 11 分制下的结果,第二部分是 21 分制下的结果,两部分之间由一个空行分隔。
11:0
11:0
1:121:0
2:1
#include
#include
using namespace std;//利用二维数组记录数据
//s11 s12为第(0-10005)/(0-5005)局 第(0-1)个人的分数
int s11[10005][2], cnt11;
int s21[5005][2], cnt21;void print() {for (int i = 0; i <= cnt11; ++i) {cout << s11[i][0] << ":" << s11[i][1] << endl;}cout << endl;for (int i = 0; i <= cnt21; ++i) {cout << s21[i][0] << ":" << s21[i][1] << endl;}cout << endl;
}int main() {char s[30];//每一行最多25个字符while (cin >> s) {for (int i = 0; s[i]; ++i) {if (s[i] == 'E') {print();return 0;}if (s[i] == 'W') {s11[cnt11][0]++;s21[cnt21][0]++;} else {s11[cnt11][1]++;s21[cnt21][1]++;}//很巧妙的将11分制 与 21分制的情况结合起来 进行处理if ((s11[cnt11][0] >= 11 || s11[cnt11][1] >= 11) && abs(s11[cnt11][0] - s11[cnt11][1]) >= 2) cnt11++;if ((s21[cnt21][0] >= 21 || s21[cnt21][1] >= 21) && abs(s21[cnt21][0] - s21[cnt21][1]) >= 2) cnt21++;}}return 0;
}
代码修改过程:
//版本1:代码冗余!且没有数据的保存(输出后立刻丢失)
#include
using namespace std;void func11(string str) {if (str[0] == 'E') cout << "0:0" << endl;int i = 0;while (str[i] != 'E') {int sc1 = 0;int sc2 = 0;while (1) {if (((sc1 >= 11 || sc2 >= 11) && abs(sc1 - sc2) >= 2) || str[i] == 'E') break;if (str[i] == 'W') sc1++;else if (str[i] == 'L') sc2++;else {continue;}i++;}cout << sc1 << ":" << sc2 << endl;}cout << endl;
}void func21(string str) {if (str[0] == 'E') cout << "0:0" <int sc1 = 0;int sc2 = 0;while (1) {if (((sc1 >= 21 || sc2 >= 21) && abs(sc1 - sc2) >= 2) || str[i] == 'E') break;if (str[i] == 'W') sc1++;else if (str[i] == 'L') sc2++;else {cout << "input error!" << endl;break;}i++;}cout << sc1 << ":" << sc2 << endl;}cout << endl;
}int main() {string str;cin >> str;func11(str);func21(str);return 0;
}
//版本2:利用二维数组保存比赛数据 在数据处理完成后再进行输出
#include
#include
using namespace std;int s11[10005][2], cnt11;
int s21[5005][2], cnt21;void func11(string str) {int i = 0;while (str[i] != 'E') {while (1) {if (((s11[cnt11][0] >= 11 || s11[cnt11][1] >= 11) && abs(s11[cnt11][0] - s11[cnt11][1]) >= 2) || str[i] == 'E') break;if (str[i] == 'W') s11[cnt11][0]++;else s11[cnt11][1]++;i++;}cout << s11[cnt11][0] << ":" << s11[cnt11][1] << endl;cnt11++;}cout << endl;
}void func21(string str) {int i = 0;while (str[i] != 'E') {while (1) {if (((s21[cnt21][0] >= 21 || s21[cnt21][1] >= 21) && abs(s21[cnt21][0] - s21[cnt21][1]) >= 2) || str[i] == 'E') break;if (str[i] == 'W') s21[cnt21][0]++;else s21[cnt21][1]++;i++;}cout << s21[cnt21][0] << ":" << s21[cnt21][1] << endl;cnt21++;}cout << endl;
}int main() {string str;cin >> str;func11(str);func21(str);return 0;
}
//版本3:while循环中的逻辑重写(单行输入)
#include
#include
using namespace std;int s11[10005][2], cnt11;
int s21[5005][2], cnt21;void print() {for (int i = 0; i <= cnt11; ++i) {cout << s11[i][0] << ":" << s11[i][1] << endl;}cout << endl;for (int i = 0; i <= cnt21; ++i) {cout << s21[i][0] << ":" << s21[i][1] << endl;}cout << endl;
} void func(string str) {int i = 0;while (str[i] != 'E') {while (1) {if (str[i] == 'E') {print();return;}if (str[i] == 'W') {s11[cnt11][0]++;s21[cnt21][0]++;} else {s11[cnt11][1]++;s21[cnt21][1]++;}if ((s11[cnt11][0] >= 11 || s11[cnt11][1] >= 11) && abs(s11[cnt11][0] - s11[cnt11][1]) >= 2) cnt11++;if ((s21[cnt21][0] >= 21 || s21[cnt21][1] >= 21) && abs(s21[cnt21][0] - s21[cnt21][1]) >= 2) cnt21++;i++;}}cout << endl;
}int main() {string str;cin >> str;if (str[0] == 'E') {print();} else {func(str);}return 0;
}
//版本4:将整行输入 改为多行输入(逻辑重写)
#include
#include
using namespace std;int s11[10005][2], cnt11;
int s21[5005][2], cnt21;void print() {for (int i = 0; i <= cnt11; ++i) {cout << s11[i][0] << ":" << s11[i][1] << endl;}cout << endl;for (int i = 0; i <= cnt21; ++i) {cout << s21[i][0] << ":" << s21[i][1] << endl;}cout << endl;
} void func(string str) {for (int i = 0; str[i]; ++i) {if (str[i] == 'E') {print();return;}if (str[i] == 'W') {s11[cnt11][0]++;s21[cnt21][0]++;} else {s11[cnt11][1]++;s21[cnt21][1]++;}if ((s11[cnt11][0] >= 11 || s11[cnt11][1] >= 11) && abs(s11[cnt11][0] - s11[cnt11][1]) >= 2) cnt11++;if ((s21[cnt21][0] >= 21 || s21[cnt21][1] >= 21) && abs(s21[cnt21][0] - s21[cnt21][1]) >= 2) cnt21++;}
}int main() {string str;while (cin >> str) {func(str);}return 0;
}
打保龄球是用一个滚球去打击十个站立的柱,将柱击倒。
一局分十轮,每轮可滚球一次或多次,以击倒的柱数为依据计分。
一局得分为十轮得分之和,而每轮的得分不仅与本轮滚球情况有关,还可能与后续一两轮的滚球情况有关。即某轮某次滚球击倒的柱数不仅要计入本轮得分,还可能会计入前一两轮得分。具体的滚球击柱规则和计分方法如下:
总之,若—轮中一次滚球或两次滚球击倒十个柱,则本轮得分是本轮首次滚球开始的连续三次滚球击倒柱数之和(其中有一次或两次不是本轮滚球)。若一轮内二次滚球击倒柱数不足十个,则本轮得分即为这两次击倒柱数之和。
下面以实例说明如下(字符“/”表示击倒当前球道上的全部的柱):
轮 1 2 3 4 5 6 7 8 9 10 11 12
击球情况 / / / 72 9/ 81 8/ / 9/ / 8/
每轮得分 30 27 19 9 18 9 20 20 20 20
累计总分 30 57 76 85 103 112 132 152 172 192
现在请你编写一个保龄球实时计分程序,用来计算和显示结束后的得分情况。
输入:
/ / / 72 9/ 81 8/ / 9/ / 8/
输出:
192
#include
using namespace std;struct node {char str[4];//每一局读入的字符数组(字符串)int num1, num2;//num1为第一球得分 num2为两球的总分int flag;//是否触发加分机制
};node m[15];//记录比赛情况int main() {//1.录入得分情况 初始化数据for (int i = 1; cin >> m[i].str; ++i) { if (m[i].str[0] == '/') {m[i].num1 = 10;m[i].num2 = 10;m[i].flag = 2;} else if (m[i].str[1] == '/') {m[i].num1 = m[i].str[0] - '0';m[i].num2 = 10;m[i].flag = 1;} else {m[i].num1 = m[i].str[0] - '0';m[i].num2 = m[i].num1 + m[i].str[1] - '0';}}//2.开始计算得分int ans = 0;for (int i = 1; i <= 10; ++i) {ans += m[i].num2;if (m[i].flag == 1) {ans += m[i + 1].num1;} else if (m[i].flag == 2){if (m[i + 1].flag == 2) {ans = ans + 10 + m[i + 2].num1;} else {ans += m[i + 1].num2;}}}cout << ans << endl;return 0;
}
//思路:先将所有数据输入存储起来,再去从前向后遍历 进行数据的处理
#include
#include
#include
using namespace std;int score[12];
string record[12];int main() {//将输入记号存入record数组中 并记录record数组中数据个数lenint len = 0;for (len = 0; cin >> record[len]; ++len);//开始计算每轮得分 并存入score数组中for (int i = 0; i < 10; ++i) {if (record[i] == "/") {if (record[i + 1] == "/") {if (record[i + 2] == "/") score[i] = 30;else score[i] = 20 + record[i + 2][0] - '0';} else {if (record[i + 1][1] == '/') score[i] = 20;else score[i] = 10 + record[i + 1][0] - '0' + record[i + 1][1] - '0';}} else if (record[i][1] == '/') {if (record[i + 1] == "/") score[i] = 20;else score[i] = 10 + record[i + 1][0] - '0';} else {score[i] = record[i][0] - '0' + record[i][1] - '0';}}for (int i = 0; i < 10; ++i) {printf("score[%d] = %d\n", i, score[i]);}//计算总分sumint sum = 0;for (int i = 0; i < 10; ++i) sum += score[i];cout << sum << endl;return 0;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HKQvgBJk-1678416725114)(assets/image-20230225113210119.png)]
在冰壶比赛中给出一个目标点 P 以及一个规定的正整数 r,每一局由甲和乙两队轮流投冰壶各 88 次后该局比赛结束。
此时哪一方的冰壶最终离目标点最近,该方得分另一方不得分。
得分方离目标点 P 距离小于或等于 r,位置较另一队所有冰壶都更接近目标点 P 的冰壶都可以得1分(比赛最多进行 10 局)
双方之间的某局比赛结束后落后一方可以弃权,此时比赛不再进行下去。
已知某一局结束时,双方的每个冰壶离目标点 P 的距离以及正整数 r,请写一个程序判断两队之间每一局比赛的得分,以及总得分。
输入
第 1 行一个正整数 r。
以下有若干行,表示对局,每一行 8 个正整数;
……
如果有一方中途弃权,则最后一行(偶数行)只有一个整数 −1,表示此时发生弃权情况;
比赛最多进行 10 局,若输入多于 21 行,请忽略 21 行后的所有内容。
输出
输出若干行,每行两个整数,中间以冒号分隔,表示每一局比赛甲乙双方的比分(甲得分在前)。
最后一行有 2 个整数,中间以冒号分隔,表示甲乙双方比赛的最终得分(甲得分在前)。
//样例1
8
5 20 18 19 3 15 13 3
20 2 17 12 5 18 10 11
20 3 4 1 2 11 9 2
1 15 19 9 8 14 11 10
15 2 10 1 19 14 3 18
15 17 21 19 24 32 19 26
-1
0:1
0:0
3:0
3:1
//样例2
8
5 20 18 19 3 15 13 3
20 2 17 12 5 18 10 11
20 3 4 1 2 11 9 2
1 15 19 9 8 14 11 10
15 2 10 1 19 14 3 18
15 17 21 19 24 32 19 26
5 1 14 13 15 2 3 11
14 7 5 19 10 12 6 9
3 14 9 8 4 8 3 10
14 6 9 4 8 2 1 5
9 8 1 2 8 8 7 18
16 8 20 19 3 1 10 5
2 13 19 2 18 9 18 3
6 5 5 20 6 17 2 18
17 3 20 6 9 3 17 17
20 10 8 12 19 19 18 20
15 18 4 18 17 14 5 16
6 14 8 14 19 7 13 7
-1
0:1
0:0
3:0
3:0
0:2
0:0
0:0
3:0
2:0
11:3
在样例 1 和样例 2 中。
样例 1 只进行了 3 局总得分是 3:1,样例 2 第 10 局比赛才有弃权总得分为 11:3。
#include
#include
using namespace std;int r;
int score[15][2];void print(int cnt) {int ans1 = 0, ans2 = 0;for (int i = 1; i < cnt; ++i) {cout << score[i][0] << ":" << score[i][1] << endl;ans1 += score[i][0];ans2 += score[i][1];}cout << ans1 << ":" << ans2 << endl;
}int main() {cin >> r;for (int i = 1; i <= 10; ++i) {int num1[10], num2[10];for (int j = 0; j < 8; ++j) {cin >> num1[j];if (num1[j] == -1) {//双方中有一方弃权print(i);return 0;}}for (int j = 0; j < 8; ++j) {cin >> num2[j];}sort(num1, num1 + 8);sort(num2, num2 + 8);//直接存入的是score而不是distanceif (num1[0] < num2[0]) {for (int j = 0; j < 8 && num1[j] < num2[0] && num1[j] <= r; ++j) score[i][0]++;} else {for (int j = 0; j < 8 && num2[j] < num1[0] && num2[j] <= r; ++j) score[i][1]++;}}print(11);return 0;
}
#include
using namespace std;int disTance[50][8];int minDistance(int i) {int ret = disTance[i][0];for (int j = 1; j < 8; ++j)if (disTance[i][j] < ret) ret = disTance[i][j];return ret;
}int countScore(int mindis, int i, int r) {int score = 0;for (int j = 0; j < 8; ++j)if (disTance[i][j] < mindis && disTance[i][j] <= r) score++;return score;
}int main() {//1.数据存储int r;int count;int flag = 1;cin >> r;for (int i = 0; flag; ++i) {for (int j = 0; j < 8 && flag; ++j) {cin >> disTance[i][j];if (disTance[i][j] == -1 || i > 19) {//双方中有一方弃权 或者 达到比赛的局数限制(20局)结束游戏count = i;flag = 0;}}}//2.数据处理int scoreA = 0;int scoreB = 0;for (int i = 0; i < count - 1; i = i + 2) {int minA = minDistance(i);int minB = minDistance(i + 1);if (minA > minB) {//乙方得分 输出具体得分int temp = countScore(minA, i + 1, r);printf("0:%d\n", temp);scoreB += temp;} else if (minB > minA) {//甲方得分 输出具体得分int temp = countScore(minB, i, r);printf("%d:0\n", temp);scoreA += temp;} else {printf("0:0\n");}}printf("%d:%d\n", scoreA, scoreB);return 0;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FqaNks6Q-1678416725117)(assets/image-20230225211652317.png)]
一个有效的邮箱地址包含以下几点要求:
比如,“mama@ta…ta” “m.am.a@t…a.t…a” 和 “m@t” 都是有效的,而 “ma@” “@ma.ma” “.mama@tata” 和 “ma.ma@tata.tata.” 不是。
可以这样来打乱自己的自制:
现在需要编写一个程序,给定一个打乱过的地址,还原出所有可能的原始有效地址。
输入
一行一个打乱过的地址,长度不超过 100。
输出
按照字典序从小到大输出所有可能的原始有效地址,每行输出一个。
nospammamaattatahr
mama@tatahr
mamaatt@ahr
nospammama@tatahr
nospammamaatt@ahr
思路:对string的操作
给出一些字符串,总长度不超过1000,统计其中大写字母的个数,并按照给定样例格式输出。
输入
一堆字符串,每两个字符串之间可能用空格、换行隔开。
输出
参照样例输出柱状统计图,每个 *
表示出现一次,注意每行不要有多余的空格。
ABC ABC.DEF()G GCC XY
354342aaaCaa aaaaaaaabcdbcd
***
* * * *
* * * * * * * * *
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
思路:
大写字母统计string str[1000] cin >> str;
,对应的字符数量增加num[str['A']]++;
统计结果输出
有 N 堆纸牌,编号分别为 1,2,…,N。
每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若干张纸牌,然后移动。
移牌规则为:
现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。
例如 N=4,4堆纸牌数分别为:① 9 ② 8 ③ 17 ④ 6
移动 3 次可达到目的:
从 ③ 取 4 张牌放到 ④ (9,8,13,10)-> 从 ③ 取 3 张牌放到 ②(9,11,10,10)-> 从 ② 取 1 张牌放到①(10,10,10,10)
输入
第一行一个整数 N。(1 ≤ N ≤ 100)
第二行 N 个整数,A1, A2, …,An。(N堆纸牌,每堆纸牌初始数,1 ≤ Ai ≤ 10000)
输出
输出一个整数表示所有堆均达到相等时的最少移动次数。
4
9 8 17 6
3
#include
using namespace std;int sum;
int n, num[105];//牌堆信息int main(){cin >> n;for (int i = 0; i < n; ++i) {cin >> num[i];sum += num[i];}int avg = sum / n;int ans = 0;//需要移动的次数for (int i = 0; i < n - 1; ++i) {if (num[i] != avg) {ans++;num[i + 1] += num[i] - avg;num[i] = avg;}}cout << ans <