GPLT练习集 L1 57--64
L1-057 PTA使我精神焕发 (5 分)
题目描述
代码
#include <iostream>
using namespace std;
int main(){
cout<<"PTA shi3 wo3 jing1 shen2 huan4 fa1 !";
return 0;
}
L1-058 6翻了 (15 分)
题目描述
代码
c语言版
#include <stdio.h>
#include<string.h>
int main() {
char str[1005];
scanf("%[^\n]",str);
int j=0;
for(int i=0 ;i<=strlen(str); i++) {
if(str[i]=='6')
j++;//计数
else { //当连续的6全部遍历完后,才执行这一步,故有i=strlen(str);
if(j>9)//判断
printf("27");
else if(j>3)
printf("9");
else {//不满足条件需要原样输出
while(j--)
printf("6");
}
printf("%c",str[i]);
j=0;
}
}
return 0;
}
说明
- 进 行 一 次 字 符 串 遍 历 进行一次字符串遍历 进行一次字符串遍历
- 当 s [ i ] = = ′ 6 ′ 时 , 开 始 计 数 , 当 s [ i ] ! = ′ 6 ′ , 计 数 结 束 , j 为 计 数 器 当s[i] == '6'时,开始计数,当s[i] !='6',计数结束,j为计数器 当s[i]==′6′时,开始计数,当s[i]!=′6′,计数结束,j为计数器
- s [ i ] ! = ′ 6 ′ 时 , 先 按 照 要 求 输 出 ( j > 9 ; j > 3 ; 其 他 原 样 输 出 ) , 然 后 原 样 输 出 其 他 字 符 , 就 不 需 要 对 字 符 串 进 行 删 减 s[i] !='6'时,先按照要求输出(j>9;j>3;其他原样输出),然后原样输出其他字符,就不需要对字符串进行删减 s[i]!=′6′时,先按照要求输出(j>9;j>3;其他原样输出),然后原样输出其他字符,就不需要对字符串进行删减
c++版
#include<bits/stdc++.h>
using namespace std;
int k;
string s;
void f(string s1 , string s2 , int n) {
while((k = s.find(s1)) != -1) {
for(int i = k + n ; ; ++i) {
if(s[i] == '6')
s.erase(--i,1);//字符串长度减1,相对应的下标也应该减1
else
break;
}
s.replace(k,n,s2);
}
}
int main() {
getline(cin , s);
f("6666666666","27",10);
f("6666","9",4);
cout << s << endl;
return 0;
}
说明
-
整 体 的 思 路 就 是 利 用 f i n d ( ) 函 数 找 到 其 目 标 字 符 串 , 但 因 为 其 目 标 字 符 串 的 长 度 是 变 量 , 不 太 好 处 理 整体的思路就是利用find()函数找到其目标字符串,但因为其目标字符串的长度是变量,不太好处理 整体的思路就是利用find()函数找到其目标字符串,但因为其目标字符串的长度是变量,不太好处理
-
针 对 变 量 的 目 标 字 符 串 , 我 们 可 以 先 确 定 临 界 的 目 标 字 符 串 长 度 ( 4 个 ′ 6 ′ 和 10 个 ′ 6 ′ ) 针对变量的目标字符串,我们可以先确定临界的目标字符串长度(4个'6'和10个'6') 针对变量的目标字符串,我们可以先确定临界的目标字符串长度(4个′6′和10个′6′)
-
先 找 到 临 界 的 目 标 字 符 串 , 然 后 对 于 长 度 大 于 其 临 界 的 长 度 时 , 我 们 可 以 利 用 e r a s e ( ) 函 数 对 它 进 行 删 减 先找到临界的目标字符串,然后对于长度大于其临界的长度时,我们可以利用erase()函数对它进行删减 先找到临界的目标字符串,然后对于长度大于其临界的长度时,我们可以利用erase()函数对它进行删减(好办法)
-
由 于 可 能 有 多 个 目 标 字 符 串 , 所 以 需 要 用 w h i l e ( ) 循 环 由于可能有多个目标字符串,所以需要用while()循环 由于可能有多个目标字符串,所以需要用while()循环
-
由 于 两 种 情 况 的 处 理 类 似 , 我 们 可 以 自 定 义 一 个 函 数 进 行 相 应 的 处 理 由于两种情况的处理类似,我们可以自定义一个函数进行相应的处理 由于两种情况的处理类似,我们可以自定义一个函数进行相应的处理
-
由 于 变 量 为 全 局 变 量 ( 在 主 函 数 外 声 明 , 定 义 , 任 何 函 数 可 以 直 接 调 用 ) , 初 始 值 自 动 为 N U L L , 然 后 用 户 输 入 , 由于变量为全局变量(在主函数外声明,定义,任何函数可以直接调用),初始值自动为NULL,然后用户输入, 由于变量为全局变量(在主函数外声明,定义,任何函数可以直接调用),初始值自动为NULL,然后用户输入,
对 字 符 串 进 行 赋 值 , 赋 值 后 的 字 符 串 可 以 直 接 被 自 定 义 函 数 调 用 , 不 需 要 传 参 对字符串进行赋值,赋值后的字符串可以直接被自定义函数调用,不需要传参 对字符串进行赋值,赋值后的字符串可以直接被自定义函数调用,不需要传参 -
如 果 变 量 为 局 部 变 量 ( 在 主 函 数 或 自 定 义 函 数 或 块 里 的 变 量 , 不 会 自 动 赋 初 始 值 , 函 数 定 义 需 传 参 , 且 函 数 调 用 完 如果变量为局部变量(在主函数或自定义函数或块里的变量,不会自动赋初始值,函数定义需传参,且函数调用完 如果变量为局部变量(在主函数或自定义函数或块里的变量,不会自动赋初始值,函数定义需传参,且函数调用完
其 变 量 消 失 ) 如 果 对 其 变 量 进 行 修 改 , 需 要 传 地 址 ( c + + 中 有 其变量消失)如果对其变量进行修改,需要传地址(c++中有 其变量消失)如果对其变量进行修改,需要传地址(c++中有& 引 用 字 符 ) , 如 果 传 值 , 值 始 终 不 变 引用字符),如果传值,值始终不变 引用字符),如果传值,值始终不变
L1-059 敲笨钟 (20 分)
题目描述
代码
c语言版
#include <stdio.h>
#include <string.h>
int main() {
int n;
scanf("%d",&n);
getchar();
while(n--) {
char str[1000];
scanf("%[^\n]",str);
getchar();
int a=strlen(str);
int flag=0,k=0,p;
for(int i=a-1 ; i>=0 ; i--)
if(str[a-2] == 'g' && str[a-3] == 'n' && str[a-4] == 'o') {
if(str[i] == ',')
if(str[i-1] == 'g'&& str[i-2] == 'n' && str[i-3] == 'o') {
flag=1;
break;
}
}
if(flag == 0)
printf( "Skipped\n");
else {
for(int j=a-1 ; j>=0 ; j--)
if(str[j] ==' ') {
k++;
if(k==3) {
p=j;
break;
}
}
for(int j=0 ; j<p ; j++)
printf("%c",str[j]);
printf(" qiao ben zhong.\n");
}
}
return 0;
}
c++版
#include <bits/stdc++.h>
using namespace std;
int n;
string s;
int main() {
cin >> n;
getchar();//吃回车
while(n--) {
getline(cin , s);
if(s.find("ong,") != -1 && s.find("ong.") != -1) {
int k = 0 , i;
for( i = s.length()-1 ; k < 3 ; --i)
if(s[i] == ' ')
++k;
cout << s.erase(i+2) << "qiao ben zhong.\n";
//cout << s.replace(i+2,s.length()-i-2,"qiao ben zhong.") << endl;
}
else
cout<<"Skipped" << endl;
}
return 0;
}
说明
- 利 用 s t r i n g 类 代 码 就 会 简 洁 很 多 利用string类代码就会简洁很多 利用string类代码就会简洁很多
- 利 用 s t r i n g 类 中 的 f i n d ( ) 函 数 可 以 更 快 的 找 到 目 标 字 符 串 利用string类中的find()函数可以更快的找到目标字符串 利用string类中的find()函数可以更快的找到目标字符串
- e r a s e ( ) ; 和 r e p l a c e ( ) 函 数 可 以 对 字 符 串 进 行 处 理 , 但 都 需 要 一 个 基 准 , 即 从 那 个 位 置 开 始 erase();和replace()函数可以对字符串进行处理,但都需要一个基准,即从那个位置开始 erase();和replace()函数可以对字符串进行处理,但都需要一个基准,即从那个位置开始
L1-060 心理阴影面积 (5 分)
题目描述
代码
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main(){
int a,b;
cin>>a>>b;
cout<<5000-50*(b-a+100);
return 0;
}
L1-061 新胖子公式 (10 分)
题目描述
根据钱江晚报官方微博的报导,最新的肥胖计算方法为:体重(kg) / 身高(m) 的平方。如果超过 25,你就是胖子。于是本题就请你编写程序
自动判断一个人到底算不算胖子。
输入格式:
输入在一行中给出两个正数,依次为一个人的体重(以 kg 为单位)和身高(以 m 为单位),其间以空格分隔。其中
体重不超过 1000 kg,身高不超过 3.0 m。
输出格式:
首先输出将该人的体重和身高代入肥胖公式的计算结果,保留小数点后 1 位。如果这个数值大于 25,就在第二行输出 PANG,否则输出 Hai Xing。
输入样例 1:
100.1 1.74
*结尾无空行*
输出样例 1:
33.1
PANG
*结尾无空行*
输入样例 2:
65 1.70
*结尾无空行*
输出样例 2:
22.5
Hai Xing
*结尾无空行*
代码
#include <iostream>
#include<math.h>
using namespace std;
int main() {
double m,n;
cin>>m>>n;
double t=m/(n*n);
printf("%.1lf\n",t);
if(t>25)
cout<<"PANG";
else
cout<<"Hai Xing";
return 0;
}
L1-062 幸运彩票 (15 分)
题目描述
彩票的号码有 6 位数字,若一张彩票的前 3 位上的数之和等于后 3 位上的数之和,则称这张彩票是幸运的。本题就请你判断给定的彩票是不是幸运的。
输入格式:
输入在第一行中给出一个正整数 N(≤ 100)。随后 N 行,每行给出一张彩票的 6 位数字。
输出格式:
对每张彩票,如果它是幸运的,就在一行中输出 You are lucky!;否则输出 Wish you good luck.。
输入样例:
2
233008
123456
*结尾无空行*
输出样例:
You are lucky!
Wish you good luck.
代码
#include <bits/stdc++.h>
using namespace std;
int n;
string s;
int main() {
cin >> n;
while(n--) {
cin >> s;
//利用string类的==号的性质
if(s[0]+s[1]+s[2]==s[3]+s[4]+s[5])
cout<<"You are lucky!"<<endl;
else
cout<<"Wish you good luck."<<endl;
}
return 0;
}
L1-063 吃鱼还是吃肉 (10 分)
题目描述
国家给出了 8 岁男宝宝的标准身高为 130 厘米、标准体重为 27 公斤;8 岁女宝宝的标准身高为 129 厘米、标准体重为 25 公斤。现在你要根据小宝宝的身高体重,给出补充营养的建议。
输入格式:
输入在第一行给出一个不超过 10 的正整数 N,随后 N 行,每行给出一位宝宝的身体数据:
性别 身高 体重
其中性别是 1 表示男生,0 表示女生。身高和体重都是不超过 200 的正整数。
输出格式:
对于每一位宝宝,在一行中给出你的建议:
如果太矮了,输出:duo chi yu!
(多吃鱼);
如果太瘦了,输出:duo chi rou!
(多吃肉);
如果正标准,输出:wan mei!
(完美);
如果太高了,输出:ni li hai!
(你厉害);
如果太胖了,输出:shao chi rou!
(少吃肉)。
先评价身高,再评价体重。两句话之间要有 1 个空格。
输入样例:
4
0 130 23
1 129 27
1 130 30
0 128 27
输出样例:
ni li hai! duo chi rou!
duo chi yu! wan mei!
wan mei! shao chi rou!
duo chi yu! shao chi rou!
代码
#include<iostream>
using namespace std;
int sex,hei,wei,n;
void f(int wei0 , int hei0) {
if(hei > hei0)
cout<<"ni li hai! ";
else if(hei < hei0)
cout<<"duo chi yu! ";
else if(hei == hei0)
cout<<"wan mei! ";
//分别判断,分别输出
if(wei > wei0)
cout<<"shao chi rou!";
else if(wei < wei0)
cout<<"duo chi rou!";
if(wei == wei0)
cout<<"wan mei!";
}
int main() {
cin>>n;
while(n--) {
cin>>sex>>hei>>wei;
if(sex) f(27,130);
else f(25,129);
cout<<endl;
}
return 0;
}
L1-064 估值一亿的AI核心代码 (20 分)
题目描述
以上图片来自新浪微博。
本题要求你实现一个稍微更值钱一点的 AI 英文问答程序,规则是:
1.无论用户说什么,首先把对方说的话在一行中原样打印出来;
2.消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉;
3.把原文中所有大写英文字母变成小写,除了 I
;
4.把原文中所有独立的 can you
、could you
对应地换成 I can
、I could
—— 这里“独立”是指被空格或标点符号分隔开的单词;
5.把原文中所有独立的 I
和 me
换成 you
;
6.把原文中所有的问号 ?
换成惊叹号 !
;
7.在一行中输出替换后的句子作为 AI 的回答。
输入格式:
输入首先在第一行给出不超过 10 的正整数 N,随后 N 行,每行给出一句不超过 1000 个字符的、以回车结尾的用户的对话,对话为非空字符串
,仅包括字母、数字、空格、可见的半角标点符号。
输出格式:
按题面要求输出,每个 AI 的回答前要加上 AI:
和一个空格。
输入样例:
6
Hello ?
Good to chat with you
can you speak Chinese?
Really?
Could you show me 5
What Is this prime? I,don 't know
输出样例:
Hello ?
AI: hello!
Good to chat with you
AI: good to chat with you
can you speak Chinese?
AI: I can speak chinese!
Really?
AI: really!
Could you show me 5
AI: I could show you 5
What Is this prime? I,don 't know
AI: what Is this prime! you,don't know
代码
#include<bits/stdc++.h>
using namespace std;
int n,k;
char ch;
string s;
int main() {
cin>>n;
getchar();
while(n--) {
getline(cin,s);
cout << s << endl << "AI: ";//规则1和7
for(int i = 0 ; i < s.length() ; ++i) {
if(isupper(s[i]) && s[i] != 'I') s[i] = tolower(s[i]);//规则3
if(s[i] == '?') s[i] = '!';//规则6
if(ispunct(s[i])) {//处理标点符号
s.insert(i," ");
if(s[i + 2] == ' ') s.insert(i+2,"1");
else s.insert(i+2,"0 ");
i += 3;
}
}
s=' '+s+' ';
while((k = s.find(" ")) != -1) s.replace(k,2," ");//清除单词间的多余空格(部分规则2)
//规则4和5,且相互独立
while((k = s.find(" could you ")) != -1) s.replace(k,11," I0 could ");//防止规则5将I改为you
while((k = s.find(" can you ")) != -1) s.replace(k,9," I0 can ");
while((k = s.find(" I ")) != -1) s.replace(k,3," you ");
while((k = s.find(" me ")) != -1) s.replace(k,4," you ");
//将规则4中的I0改为I
while((k = s.find(" I0 ")) != -1) s.replace(k,4," I ");
for(int i = 0 ; s[i] != '\0' ;i++) {
if(!ispunct(s[i])) continue;
if(s[i + 1] == '1') s.erase(i + 1 , 1);//清除"1"
else s.erase(i + 1 , 2);//清除"0 "
if(s[i-1] == ' ') s.erase((i--)-1,1);//清除标点符号前的空格(部分规则2)
}
//while(s[0]==' ')s.erase(0,1);//清除首空格(部分规则2)
s.erase(0,s.find_first_not_of(" "));
//while(s[s.length()-1]==' ')s.erase(s.length()-1,1);//清除尾空格
s.erase(s.find_last_not_of(" ") + 1);
cout<<s<<endl;
}
return 0;
}
说明:
- 这 7 条 规 则 有 些 是 相 互 影 响 的 , 有 些 是 独 立 的 这7条规则有些是相互影响的,有些是独立的 这7条规则有些是相互影响的,有些是独立的
- 规 则 1 , 3 , 6 , 7 是 相 互 独 立 的 , 可 以 先 处 理 规则1,3,6,7是相互独立的,可以先处理 规则1,3,6,7是相互独立的,可以先处理
-
其
中
规
则
4
,
5
是
一
类
(
其中规则4,5是一类(
其中规则4,5是一类(
can you
、could you
中 间 只 有 空 格 , 没 有 标 点 符 号 的 可 能 , 它 们 是 一 个 整 体 ) 中间只有空格,没有标点符号的可能,它们是一个整体) 中间只有空格,没有标点符号的可能,它们是一个整体)----一开始理解错了意思
规 则 4 和 5 是 相 互 独 立 的 , 这 个 坑 死 了 很 多 人 规则4和5是相互独立的,这个坑死了很多人 规则4和5是相互独立的,这个坑死了很多人 -
规
则
2
处
理
非
句
首
句
尾
的
空
格
有
很
多
种
方
法
规则2处理非句首句尾的空格有很多种方法
规则2处理非句首句尾的空格有很多种方法
① 利 用 遍 历 字 符 串 的 各 个 元 素 , 先 定 位 第 一 次 出 现 空 格 的 位 置 , 然 后 再 从 这 个 位 置 继 续 循 环 遍 历 , 定 位 最 后 ①利用遍历字符串的各个元素,先定位第一次出现空格的位置,然后再从这个位置继续循环遍历,定位最后 ①利用遍历字符串的各个元素,先定位第一次出现空格的位置,然后再从这个位置继续循环遍历,定位最后
出 现 空 格 的 位 置 , 这 样 就 能 计 算 出 之 间 空 格 的 数 量 − − − − − 出现空格的位置,这样就能计算出之间空格的数量----- 出现空格的位置,这样就能计算出之间空格的数量−−−−−(复杂度高
)
for(int i = 0 ; i < s.length() ; ++i) {
if(s[i] == ' ') {//第一次出现空格的位置
for(j = i + 1 ; j < s.length() ; ++j)
if(s[j] != ' ') break;//最后一次出现连续空格的位置
if(ispunct(s[j])) s.erase(i,j-i);//清除标点符号前的
else s.erase(i,j-i-1);//清除单词间的空格
i = j;
}
}
②
先
通
过
f
i
n
d
(
)
函
数
找
到
有
两
个
空
格
的
位
置
,
并
清
除
它
,
这
样
其
之
间
就
只
剩
下
一
个
空
格
清
除
单
词
和
标
点
符
号
间
的
多
余
空
格
②先通过find()函数找到有两个空格的位置,并清除它,这样其之间就只剩下一个空格清除单词和标点符号间的多余空格
②先通过find()函数找到有两个空格的位置,并清除它,这样其之间就只剩下一个空格清除单词和标点符号间的多余空格
然
后
再
清
除
标
点
符
号
前
的
空
格
然后再清除标点符号前的空格
然后再清除标点符号前的空格----(一重循环就解决
)
while((k = s.find(" ")) != -1)
s.replace(k,2," ");//清除单词和标点符号间的多余空格(部分规则2)
for(int i = 0 ; s[i] != '\0' ;i++) {
if(!ispunct(s[i])) continue;
if(s[i-1] == ' ') s.erase((i--)-1,1);//清除标点符号前的空格(部分规则2)
}
-
清
除
句
首
句
尾
的
空
格
,
也
有
两
种
情
况
清除句首句尾的空格,也有两种情况
清除句首句尾的空格,也有两种情况
① 利 用 f i n d ( ) 函 数 找 到 空 格 , 并 清 除 它 ①利用find()函数找到空格,并清除它 ①利用find()函数找到空格,并清除它
② 利 用 ②利用 ②利用s.find_first_not_of( )
和 和 和s.find_last_not_of( )
$函数
s.find_first_not_of( )
从 前 往 后 查 找 在 原 字 符 串 中 第 一 个 与 指 定 字 符 串 ( 或 字 符 ) 中 的 任 一 字 符 都 不 匹 配 的 字 符 , 返 回 它 的 位 置 . 从前往后查找在原字符串中第一个与指定字符串(或字符)中的任一字符都不匹配的字符,返回它的位置. 从前往后查找在原字符串中第一个与指定字符串(或字符)中的任一字符都不匹配的字符,返回它的位置.
若 查 找 失 败 则 返 回 n p o s 。 ( n p o s 定 义 为 保 证 大 于 任 何 有 效 下 标 的 值 。 ) 若查找失败则返回npos。(npos定义为保证大于任何有效下标的值。) 若查找失败则返回npos。(npos定义为保证大于任何有效下标的值。)
s.find_last_not_of( )
从 后 往 前 查 找 在 原 字 符 串 中 最 后 一 个 与 指 定 字 符 串 ( 或 字 符 ) 中 的 任 一 字 符 都 不 匹 配 的 字 符 , 返 回 它 的 位 置 . 从后往前查找在原字符串中最后一个与指定字符串(或字符)中的任一字符都不匹配的字符,返回它的位置. 从后往前查找在原字符串中最后一个与指定字符串(或字符)中的任一字符都不匹配的字符,返回它的位置.
若 查 找 失 败 则 返 回 n p o s 。 ( n p o s 定 义 为 保 证 大 于 任 何 有 效 下 标 的 值 。 ) 若查找失败则返回npos。(npos定义为保证大于任何有效下标的值。) 若查找失败则返回npos。(npos定义为保证大于任何有效下标的值。)
详 细 解 释 : 详细解释: 详细解释:C++string中find_first_not_of()函数和find_last_not_of()函数
/*
while(s[0]==' ')
s.erase(0,1);//清除首空格(部分规则2)
*/
s.erase(0,s.find_first_not_of(" "));
/*
while(s[s.length()-1]==' ')
s.erase(s.length()-1,1);//清除尾空格
*/
s.erase(s.find_last_not_of(" ") + 1);
6.
本
题
的
难
点
就
是
如
何
替
换
规
则
4
和
5
的
内
容
本题的难点就是如何替换规则4和5的内容
本题的难点就是如何替换规则4和5的内容
①
我
们
不
知
道
其
前
和
其
后
是
空
格
还
是
标
点
符
号
①我们不知道其前和其后是空格还是标点符号
①我们不知道其前和其后是空格还是标点符号
②
若
它
们
再
句
首
或
句
尾
怎
么
处
理
②若它们再句首或句尾怎么处理
②若它们再句首或句尾怎么处理
①和②的处理方法:不管如何,都让要替换的字符串前面和后面都为空格
[1]若在句首或句尾,直接利用string类的性质
s=' '+s+' ';
[2]若为标点符号,则利用insert()
函数插入空格
1)若在字符串后面有标点符号,则在标点符号前插入即可
2)若在字符串前面有标点符号,这时如果要换字符串若直接插入空格,到时候删除的时候就会误删本来就有的空格,所以还需添加一个标识符
③
规
则
4
和
5
相
互
独
立
,
③规则4和5相互独立,
③规则4和5相互独立,can you
变
成
变成
变成I can
其
中
′
I
′
不
会
在
规
则
5
中
变
成
"
y
o
u
"
其中'I'不会在规则5中变成"you"
其中′I′不会在规则5中变成"you"