7-1 估值一亿的AI核心代码
题意:本题要求你实现一个稍微更值钱一点的 AI 英文问答程序,规则是:
- 无论用户说什么,首先把对方说的话在一行中原样打印出来;
- 消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉;
- 把原文中所有大写英文字母变成小写,除了
I
; - 把原文中所有独立的
can you
、could you
对应地换成I can
、I could
—— 这里“独立”是指被空格或标点符号分隔开的单词; - 把原文中所有独立的
I
和me
换成you
; - 把原文中所有的问号
?
换成惊叹号!
; - 在一行中输出替换后的句子作为 AI 的回答。
题解:把除 ‘ I ' 的大写字母改为小写字母,在每个非字母和数字之前加空格,用stringstream消除单词间的空格。还要在输出每个单词时判断第一个字符是不是标点符号如果是在这个单词前不能输出空格。如果第一个单词的第一个字符就是标点符号还是要输出空格,因为按题面要求输出,每个 AI 的回答前要加上 AI:
和一个空格。(我一开始把str定义在while循环外就一直错错,定义在while循环里面就好了,我不懂/(ㄒoㄒ)/~~)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<sstream> #include<string> #include<cmath> using namespace std; int main(){ int n; cin >> n; getchar(); string s,ts; stringstream ss; while(n--){ string str[1010]; getline(cin,s); cout<<s<<endl; for(int i=0;i<s.size();i++){ if(isalnum(s[i])){ if(s[i]!='I') s[i]=tolower(s[i]); }else{ s.insert(i," "); i++; } if(s[i]=='?'){ s[i]='!'; } } ss.clear(); ss<<s; int cnt=0; while(ss>>ts){ str[cnt++]=ts; } cout<<"AI:"; if(!isalnum(str[0][0])){ cout<<" "; } for(int i=0;i<cnt;++i){ if(!isalnum(str[i][0])){ cout<<str[i]; }else if((str[i]=="can"||str[i]=="could")&&str[i+1]=="you"){ cout<<" I " <<str[i]; i++; }else if(str[i]=="I"||str[i]=="me"){ cout<<" you"; }else{ cout<<" "<<str[i]; } } cout<<endl; } return 0; }
7-3 N个数求和
题意:就是求N
个数字的和。这些数字是以有理数分子/分母
的形式给出的,你输出的和也必须是有理数的形式。输出上述数字和的最简形式 —— 即将结果写成整数部分 分数部分
,其中分数部分写成分子/分母
,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。
题解:每输入一个有理数,就和之前的累加,再化简
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<algorithm> #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<string> using namespace std; typedef long long ll; ll gcd(ll a,ll b){ return b?gcd(b,a%b):a; } int main(){ ios::sync_with_stdio(false); ll n; cin>>n; ll sum1=0,sum2=1; for(ll i=1;i<=n;i++){ ll a,b,temp,item,x,y; char c; cin>>a>>c>>b; x=a*sum2+b*sum1; y=b*sum2; item=gcd(sum1,sum2); sum1=x/item; sum2=y/item; } ll t=gcd(sum1,sum2); sum1=sum1/t; sum2=sum2/t; if(sum1%sum2==0){ cout<<sum1/sum2<<endl; }else if(sum1>sum2){ cout<<sum1/sum2<<" "<<sum1%sum2<<'/'<<sum2<<endl; }else{ cout<<sum1<<'/'<<sum2<<endl; } return 0; }
7-9 名人堂与代金券
题意:总评分在 [G, 100] 区间内者,可以得到 50 元 PAT 代金券;在 [60, G) 区间内者,可以得到 20 元PAT代金券。总评成绩前 K 名的学生列入课程“名人堂”。首先在一行中输出发出的 PAT 代金券的总面值。然后按总评成绩非升序输出进入名人堂的学生的名次、账号和成绩,其间以 1 个空格分隔。需要注意的是:成绩相同的学生享有并列的排名,排名并列时,按账号的字母序升序输出。
题解:排名并列时,按账号的字母序升序输出,根据字母序先排一下序。写一个函数成绩相同的学生享有并列的排名,按照排好后的编号来,再减掉前面和他有相同排名的人就可以了;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<string> #include<cmath> using namespace std; struct node{ string s; int score; }; bool cmp(node a,node b){ if(a. score==b.score){ return a.s<b.s; } return a.score>b.score; } int main(){ node a[10010]; int n,g,k; int sum=0,cnt=1,flag=0; cin>>n>>g>>k; for(int i=1;i<=n;i++){ cin>>a[i].s>>a[i].score; if(a[i].score>=g){ sum+=50; }else if(a[i].score>=60){ sum+=20; } } cout<<sum<<endl; sort(a+1,a+1+n,cmp); cout<<"1 "<<a[1].s<<" "<<a[1].score<<endl; for(int i=2;i<=n;i++){ if(a[i].score==a[i-1].score){ flag++; if(i-flag>k)break; cout<<i-flag<<" "<<a[i].s<<" "<<a[i].score<<endl; }else{ flag=0; if(i>k) break; cout<<i<<" "<<a[i].s<<" "<<a[i].score<<endl; } } return 0; }