7-1 估值一亿的AI核心代码 (20分)
本题要求你实现一个稍微更值钱一点的 AI 英文问答程序,规则是:
- 无论用户说什么,首先把对方说的话在一行中原样打印出来;
- 消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉;
- 把原文中所有大写英文字母变成小写,除了
I
; - 把原文中所有独立的
can you
、could you
对应地换成I can
、I could
—— 这里“独立”是指被空格或标点符号分隔开的单词; - 把原文中所有独立的
I
和me
换成you
; - 把原文中所有的问号
?
换成惊叹号!
; - 在一行中输出替换后的句子作为 AI 的回答。
代码:
#include <bits/stdc++.h> using namespace std; int main() { int n; string str; vector<string> v; cin>>n; getchar(); while(n--){ getline(cin,str); cout<<str<<endl<<"AI: "; for(int i=0;i<str.size();i++){ if(str[i]>='A'&&str[i]<='Z'){ if(str[i]!='I'){ str[i]=str[i]-'A'+'a'; } }else if((str[i]>='0'&&str[i]<='9')||(str[i]>='a'&&str[i]<='z')){ continue; }else if(str[i]!=' '){ str.insert(i," "); i++; } if(str[i] =='?'){ str[i]='!'; } } string temp=""; for(int i=0;i<str.size();i++){ if(str[i]!=' '){ temp+=str[i]; }else{ if(temp!=""){ v.push_back(temp); temp=""; } } } if(temp!=""){ v.push_back(temp); } for(int i=0;i<v.size();i++){ if(v[i]=="I"||v[i]=="me"){ v[i]="you"; }else if(v[i]=="can"||v[i]=="could"){ if((i+1)<v.size()){ if(v[i+1]=="you"){ v[i+1] = v[i]; v[i]="I"; } } } } for(int i=0;i<v.size();i++){ cout<<v[i]; if(i==v.size()-1){ break; } if((v[i+1][0]>='0'&&v[i+1][0]<='9')||(v[i+1][0]>='a'&&v[i+1][0]<='z')||(v[i+1][0]=='I')){ printf(" "); } } printf(" "); v.clear(); } return 0; }
据说一个人的标准体重应该是其身高(单位:厘米)减去100、再乘以0.9所得到的公斤数。已知市斤的数值是公斤数值的两倍。现给定某人身高,请你计算其标准体重应该是多少?(顺便也悄悄给自己算一下吧……)
输入格式:
输入第一行给出一个正整数H
(100 < H ≤ 300),为某人身高。
输出格式:
在一行中输出对应的标准体重,单位为市斤,保留小数点后1位。
输入样例:
169
输出样例:
124.2
#include <bits/stdc++.h> using namespace std; int main() { double a; cin>>a; printf("%.1f",(a-100)*0.9*2); return 0; }
本题的要求很简单,就是求N
个数字的和。麻烦的是,这些数字是以有理数分子/分母
的形式给出的,你输出的和也必须是有理数的形式。
输入格式:
输入第一行给出一个正整数N
(≤100)。随后一行按格式a1/b1 a2/b2 ...
给出N
个有理数。题目保证所有分子和分母都在长整型范围内。另外,负数的符号一定出现在分子前面。
输出格式:
输出上述数字和的最简形式 —— 即将结果写成整数部分 分数部分
,其中分数部分写成分子/分母
,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。
输入样例1:
5
2/5 4/15 1/30 -2/60 8/3
输出样例1:
3 1/3
输入样例2:
2
4/3 2/3
输出样例2:
2
输入样例3:
3
1/3 -1/6 1/8
输出样例3:
7/24
#include <bits/stdc++.h> using namespace std; int main() { int n; long long l; long long a,b,c,d; scanf("%d",&n); scanf("%lld/%lld",&a,&b); int t=__gcd(a,b); if(a) { a/=t; b/=t; } int i=1; while (i<n) { scanf("%lld/%lld",&c,&d); l= b / __gcd(b,d) * d; a = a*l/b+c*l/d; b = l; int t = __gcd(a,b); if(t != 0) { a = a / t; b = b / t; } i++; } if(a&&a/b==0) printf("%lld/%lld ",a%b,b); else if(a%b==0) printf("%lld ",a/b); else printf("%lld %lld/%lld ",a/b,a%b,b); return 0; }
给定两个整数A和B,输出从A到B的所有整数以及这些数的和。
输入格式:
输入在一行中给出2个整数A和B,其中−100≤A≤B≤100,其间以空格分隔。
输出格式:
首先顺序输出从A到B的所有整数,每5个数字占一行,每个数字占5个字符宽度,向右对齐。最后在一行中按Sum = X
的格式输出全部数字的和X
。
输入样例:
-3 8
输出样例:
-3 -2 -1 0 1 2 3 4 5 6 7 8 Sum = 30
#include <bits/stdc++.h> using namespace std; int main() { int a,b,flag=0,sum=0,i; cin>>a>>b; for(i=a;i<=b;i++){ sum+=i; if(flag==4){ printf("%5d ",i); flag=0; }else{ printf("%5d",i); flag++; } } if(flag!=0){ cout<<endl; } cout<<"Sum = "<<sum<<endl; }
“666”是一种网络用语,大概是表示某人很厉害、我们很佩服的意思。最近又衍生出另一个数字“9”,意思是“6翻了”,实在太厉害的意思。如果你以为这就是厉害的最高境界,那就错啦 —— 目前的最高境界是数字“27”,因为这是 3 个 “9”!
本题就请你编写程序,将那些过时的、只会用一连串“6666……6”表达仰慕的句子,翻译成最新的高级表达。
输入格式:
输入在一行中给出一句话,即一个非空字符串,由不超过 1000 个英文字母、数字和空格组成,以回车结束。
输出格式:
从左到右扫描输入的句子:如果句子中有超过 3 个连续的 6,则将这串连续的 6 替换成 9;但如果有超过 9 个连续的 6,则将这串连续的 6 替换成 27。其他内容不受影响,原样输出。
输入样例:
it is so 666 really 6666 what else can I say 6666666666
输出样例:
it is so 666 really 9 what else can I say 27
#include <bits/stdc++.h> using namespace std; int main() { string s; int count=0; getline(cin,s); for(int i=0; i<s.length(); i++) { if(s[i]=='6') { count++; } else if(count!=0) { if(count>9) { cout<<27; } else if(count>3) { cout<<9; } else{ while(count--){ cout<<6; } } count=0; cout<<s[i]; } else { cout<<s[i]; } } if(count!=0) { if(count>9) { cout<<27; } else if(count>3) { cout<<9; } else{ while(count--){ cout<<6; } } } cout<<endl; return 0; }
“一帮一学习小组”是中小学中常见的学习组织方式,老师把学习成绩靠前的学生跟学习成绩靠后的学生排在一组。本题就请你编写程序帮助老师自动完成这个分配工作,即在得到全班学生的排名后,在当前尚未分组的学生中,将名次最靠前的学生与名次最靠后的异性学生分为一组。
输入格式:
输入第一行给出正偶数N
(≤50),即全班学生的人数。此后N
行,按照名次从高到低的顺序给出每个学生的性别(0代表女生,1代表男生)和姓名(不超过8个英文字母的非空字符串),其间以1个空格分隔。这里保证本班男女比例是1:1,并且没有并列名次。
输出格式:
每行输出一组两个学生的姓名,其间以1个空格分隔。名次高的学生在前,名次低的学生在后。小组的输出顺序按照前面学生的名次从高到低排列。
输入样例:
8
0 Amy
1 Tom
1 Bill
0 Cindy
0 Maya
1 John
1 Jack
0 Linda
输出样例:
Amy Jack
Tom Linda
Bill Maya
Cindy John
#include <bits/stdc++.h> using namespace std; struct Node { int sex; char name[10]; int flag=0; }; int main (void) { int n; scanf("%d", &n); Node stu[n]; for(int i = 0; i < n; i++) { scanf("%d %s", &stu[i].sex, &stu[i].name); } for(int i = 0; i < n / 2; i++) { for(int j = n - 1; j >= n / 2; j--) { if(stu[i].sex != stu[j].sex && stu[i].flag == 0 && stu[j].flag == 0) { stu[i].flag = 1; stu[j].flag = 1; printf("%s %s ", stu[i].name, stu[j].name); } } } return 0; }
据说一个人的标准体重应该是其身高(单位:厘米)减去100、再乘以0.9所得到的公斤数。真实体重与标准体重误差在10%以内都是完美身材(即 | 真实体重 − 标准体重 | < 标准体重×10%)。已知市斤是公斤的两倍。现给定一群人的身高和实际体重,请你告诉他们是否太胖或太瘦了。
输入格式:
输入第一行给出一个正整数N
(≤ 20)。随后N
行,每行给出两个整数,分别是一个人的身高H
(120 < H < 200;单位:厘米)和真实体重W
(50 < W ≤ 300;单位:市斤),其间以空格分隔。
输出格式:
为每个人输出一行结论:如果是完美身材,输出You are wan mei!
;如果太胖了,输出You are tai pang le!
;否则输出You are tai shou le!
。
输入样例:
3
169 136
150 81
178 155
输出样例:
You are wan mei!
You are tai shou le!
You are tai pang le!
#include <bits/stdc++.h> using namespace std; int main() { int n; cin>>n; while(n--){ double a,b; cin>>a>>b; a=(a-100)*0.9*2; if(fabs(b-a)<a*0.1){ // cout<<fabs(b-a)<<endl; //cout<<a*0.1<<endl; cout<<"You are wan mei!"<<endl; }else if(b<a){ cout<<"You are tai shou le!"<<endl; }else{ cout<<"You are tai pang le!"<<endl; } } return 0; }
这次真的没骗你 —— 这道超级简单的题目没有任何输入。
你只需要在一行中输出事实:This is a simple problem.
就可以了。
#include <bits/stdc++.h> using namespace std; int main() { cout<<"This is a simple problem."<<endl; return 0; }
对于在中国大学MOOC(http://www.icourse163.org/ )学习“数据结构”课程的学生,想要获得一张合格证书,总评成绩必须达到 60 分及以上,并且有另加福利:总评分在 [G, 100] 区间内者,可以得到 50 元 PAT 代金券;在 [60, G) 区间内者,可以得到 20 元PAT代金券。全国考点通用,一年有效。同时任课老师还会把总评成绩前 K 名的学生列入课程“名人堂”。本题就请你编写程序,帮助老师列出名人堂的学生,并统计一共发出了面值多少元的 PAT 代金券。
输入格式:
输入在第一行给出 3 个整数,分别是 N(不超过 10 000 的正整数,为学生总数)、G(在 (60,100) 区间内的整数,为题面中描述的代金券等级分界线)、K(不超过 100 且不超过 N 的正整数,为进入名人堂的最低名次)。接下来 N 行,每行给出一位学生的账号(长度不超过15位、不带空格的字符串)和总评成绩(区间 [0, 100] 内的整数),其间以空格分隔。题目保证没有重复的账号。
输出格式:
首先在一行中输出发出的 PAT 代金券的总面值。然后按总评成绩非升序输出进入名人堂的学生的名次、账号和成绩,其间以 1 个空格分隔。需要注意的是:成绩相同的学生享有并列的排名,排名并列时,按账号的字母序升序输出。
输入样例:
10 80 5
cy@zju.edu.cn 78
cy@pat-edu.com 87
1001@qq.com 65
uh-oh@163.com 96
test@126.com 39
anyone@qq.com 87
zoe@mit.edu 80
jack@ucla.edu 88
bob@cmu.edu 80
ken@163.com 70
输出样例:
360
1 uh-oh@163.com 96
2 jack@ucla.edu 88
3 anyone@qq.com 87
3 cy@pat-edu.com 87
5 bob@cmu.edu 80
5 zoe@mit.edu 80
#include <bits/stdc++.h> #include<algorithm> #define p123 printf("123 "); #define pn printf(" "); #define pk printf(" "); #define ll long long #define re(n,a) memset(n,a,sizeof(n)); #define len(a) strlen(a) #define eps 1e-6 using namespace std; struct hum{ int sco; int rank; string id; }h[10010]; bool cmp(hum a,hum b){ if(a.sco!=b.sco){ return a.sco>b.sco; }else{ return a.id<b.id;//差点忘了字符串可以这么比较了233 } } int main() { int n,g,k,i,sum=0; cin>>n>>g>>k; for(i=0;i<n;i++){ cin>>h[i].id>>h[i].sco; if(h[i].sco>=g){ sum+=50; }else if(h[i].sco>=60){ sum+=20; } } cout<<sum<<endl; sort(h,h+n,cmp); h[0].rank=1; int flag=1; for(i=0;i<n;i++){ flag++; if(h[i].sco==h[i+1].sco){ h[i+1].rank=h[i].rank; }else{ h[i+1].rank=flag;//不是=h[i].rank+1 } if(h[i].rank<=k) cout<<h[i].rank<<" "<<h[i].id<<" "<<h[i].sco<<endl; else break; } return 0; }
给定一个带整数键值的链表 L,你需要把其中绝对值重复的键值结点删掉。即对每个键值 K,只有第一个绝对值等于 K 的结点被保留。同时,所有被删除的结点须被保存在另一个链表上。例如给定 L 为 21→-15→-15→-7→15,你需要输出去重后的链表 21→-15→-7,还有被删除的链表 -15→15。
输入格式:
输入在第一行给出 L 的第一个结点的地址和一个正整数 N(≤105,为结点总数)。一个结点的地址是非负的 5 位整数,空地址 NULL 用 -1 来表示。
随后 N 行,每行按以下格式描述一个结点:
地址 键值 下一个结点
其中地址
是该结点的地址,键值
是绝对值不超过104的整数,下一个结点
是下个结点的地址。
输出格式:
首先输出去重后的链表,然后输出被删除的链表。每个结点占一行,按输入的格式输出。
输入样例:
00100 5
99999 -7 87654
23854 -15 00000
87654 15 -1
00000 -15 99999
00100 21 23854
输出样例:
00100 21 23854 23854 -15 99999 99999 -7 -1 00000 -15 87654 87654 15 -1
#include <bits/stdc++.h> #include<algorithm> #define p123 printf("123 "); #define pn printf(" "); #define pk printf(" "); #define ll long long #define re(n,a) memset(n,a,sizeof(n)); #define len(a) strlen(a) #define eps 1e-6 using namespace std; const int N=1e5+3; struct node{ int data; int next; }lis[N]; int main() { int head,n,ad,i; cin>>head>>n; for(i=0;i<n;i++){ cin>>ad; cin>>lis[ad].data>>lis[ad].next;//我 没 想 到 } int ans[N],k1=0;//剩下的结点,结点的数量 int res[N],k2=0;//被删结点 bool vis[N]={0};//判断这个值存不存在 int p=head; while(p!=-1){ int m=abs(lis[p].data); if(!vis[m]){ ans[k1++]=p; vis[m]=1; }else{ res[k2++]=p; } p=lis[p].next; } printf("%05d",head); for(int i = 1; i < k1; i++) { printf(" %d %05d %05d", lis[ans[i-1]].data, ans[i], ans[i]); } printf(" %d -1 ", lis[ans[k1-1]].data); if(k2 > 0) { printf("%05d", res[0]); for(int i = 1; i < k2; i++) { printf(" %d %05d %05d", lis[res[i-1]].data, res[i], res[i]); } printf(" %d -1", lis[res[k2-1]].data); } return 0; }