ACM 实验室2020.10.10天梯赛练习*2 补题

7-1 估值一亿的AI核心代码 (20分)

本题要求你实现一个稍微更值钱一点的 AI 英文问答程序,规则是:

  • 无论用户说什么,首先把对方说的话在一行中原样打印出来;
  • 消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉;
  • 把原文中所有大写英文字母变成小写,除了 I
  • 把原文中所有独立的 can youcould you 对应地换成 I canI 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("\n");
        v.clear();
    }
    return 0;
}
7-2 是不是太胖了 (5分)

据说一个人的标准体重应该是其身高(单位:厘米)减去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;
}
7-3 N个数求和 (20分)

本题的要求很简单,就是求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\n",a%b,b);
    else if(a%b==0)
    printf("%lld\n",a/b);
    else
        printf("%lld %lld/%lld\n",a/b,a%b,b);

    return 0;
}

 

7-4 求整数段和 (10分)

给定两个整数A和B,输出从A到B的所有整数以及这些数的和。

输入格式:

输入在一行中给出2个整数A和B,其中100AB100,其间以空格分隔。

输出格式:

首先顺序输出从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\n",i);
            flag=0;
        }else{
            printf("%5d",i);
            flag++;
        }
    }
    if(flag!=0){
        cout<<endl;
    }
    cout<<"Sum = "<<sum<<endl;

}
7-5 6翻了 (15分)

 

“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;
}
7-6 一帮一 (15分)

“一帮一学习小组”是中小学中常见的学习组织方式,老师把学习成绩靠前的学生跟学习成绩靠后的学生排在一组。本题就请你编写程序帮助老师自动完成这个分配工作,即在得到全班学生的排名后,在当前尚未分组的学生中,将名次最靠前的学生与名次最靠后的异性学生分为一组。

输入格式:

输入第一行给出正偶数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\n", stu[i].name, stu[j].name);
            }
        }
    }
    return 0;
}
7-7 到底是不是太胖了 (10分)

据说一个人的标准体重应该是其身高(单位:厘米)减去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;
}
7-8 简单题 (5分)

这次真的没骗你 —— 这道超级简单的题目没有任何输入。

你只需要在一行中输出事实:This is a simple problem. 就可以了。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    cout<<"This is a simple problem."<<endl;
    return 0;
}

 

7-9 名人堂与代金券 (25分)

对于在中国大学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\n");
#define pn printf("\n");
#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;
}

 

7-10 链表去重 (25分)

给定一个带整数键值的链表 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\n");
#define pn printf("\n");
#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\n%05d", lis[ans[i-1]].data, ans[i], ans[i]);
    }
    printf(" %d -1\n", lis[ans[k1-1]].data);
    if(k2 > 0)
    {
        printf("%05d", res[0]);
        for(int i = 1; i < k2; i++)
        {
            printf(" %d %05d\n%05d", lis[res[i-1]].data, res[i], res[i]);
        }
        printf(" %d -1", lis[res[k2-1]].data);
    }
    return 0;
}

 

 



 
posted @ 2020-10-18 19:11  一只幽灵飘过  阅读(437)  评论(0编辑  收藏  举报