2024/1/17北化寒假集训题解

目录

 问题 A: 青年歌手大赛-评委会打分

问题 B: I don't want to pay for the Late Jar

问题 C: 配对碱基链

问题 D: 矩阵交换行

问题 E: 用递归函数输出斐波那契数列第n项

问题 F: 递归法求Hermite多项式的值

问题 G: [蓝桥杯2017初赛]兴趣小组

问题 H: [蓝桥杯2018初赛]测试次数

问题 I: ACM 罚时

问题 J: 2.4.7 集合运算

问题 K: 双刀流银色战车

问题 L: 时间要开始加速了

问题 M: 2.4.9.2 双重队列

 问题 A: 青年歌手大赛-评委会打分

题目描述

在青年歌手大奖赛中,评委会给参赛选手打分。
选手得分规则为去掉一个最高分和一个最低分、然后计算平均得分,请编程输出某选手的得分。

输入

输入数据有多组,每组占一行.
每行的第一个数是n(2<n≤100),表示评委的人数,然后是n个评委的打分。

输出

对于每组输入数据,输出选手的得分,结果保留2位小数,每组输出占一行。

样例输入 
3 99 98 97
4 100 99 98 97
样例输出 
98.00
98.50
题解 
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    while(cin>>n)
    {
        float a[n];
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
        }
        sort(a,a+n);
        float sum=0;
        for(int i=1;i<n-1;i++)
        {
            sum+=a[i];
        }
        printf("%.2f",sum/(n-2));
        cout<<endl;
    }
    return 0;
}

问题 B: I don't want to pay for the Late Jar

题目描述

来自IT部门的尼娜需要你的帮助,解决她面临的一个日常难题。她随时都可以休息吃午饭。但由于工作原因,她只能根据当天的需要,休息s分钟。她只要迟到,都要付给罐子1令吉。 她根据自己的经验,列出了自己最喜欢的餐厅,以及她在每家餐厅午餐需要花费的时问(1≤ti≤109)。她还为每家餐馆指定了一个价值(1≤fi≤109),这个价值表明她愿意付出多少额外的钱,但仍然感到快乐。 例如,如果她需要在x餐厅用餐tx分钟,她认为价值为RMfx。如果tx≤s,那么她是完全幸福的,就好像她保存了RMfx。 但是如果tx>s,她会节省fx-(tx-s)。请帮助她找到她最喜欢的餐厅,同时节省最多的钱。此外,请记住,她每天只能选择一家餐厅用午餐。

输入

第一行包含 1个整数d (1≤d≤10)天数。第二行包含两个空格分隔的整数n(1≤n≤104)和s(1≤s≤109),尼娜列表中的餐厅数目和她当天的午休时间。下一个n行包含两个空间分隔的整数fi(1≤fi≤109)和ti(1≤ti≤109)是第i个餐厅的特征。

输出

一行打印一个整数--她每天为幸福节省的最大金额。

样例输入 
2
2 5
3 3
4 5

1 5
1 7
样例输出 
Case #1:4
Case #2:-1
题解
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int d;
    cin>>d;
    for(int i=0;i<d;i++)
    {
        int n,s;
        cin>>n>>s;
        int t[n],f[n];
        for(int j=0;j<n;j++)
        {
            cin>>f[j]>>t[j];
        }
        int c[n];
        for(int j=0;j<n;j++)
        {
            if(t[j]<=s)
            {
                c[j]=f[j];
            }
            else
            {
                c[j]=f[j]-(t[j]-s);
            }
        }
        sort(c,c+n);
        cout<<"Case #"<<i+1<<":"<<c[n-1]<<endl;
    }
    return 0;
}

问题 C: 配对碱基链

题目描述

脱氧核糖核酸(DNA)由两条互补的碱基链以双螺旋的方式结合而成。而构成DNA的碱基共有4种,分别为腺瞟呤(A)、鸟嘌呤(G)、胸腺嘧啶(T)和胞嘧啶(C)。我们知道,在两条互补碱基链的对应位置上,腺瞟呤总是和胸腺嘧啶配对,鸟嘌呤总是和胞嘧啶配对。你的任务就是根据一条单链上的碱基序列,给出对应的互补链上的碱基序列。

输入

一个字符串,表示一条碱基链。这个字符串只含有大写字母A、T、G、C,分别表示腺瞟呤、胸腺嘧啶、鸟嘌呤和胞嘧啶。字符串长度不超过255。

输出

一个只含有大写字母A、T、G、C的字符串,为与输入的碱基链互补的碱基链。

样例输入 
ATATGGATGGTGTTTGGCTCTG
样例输出 
TATACCTACCACAAACCGAGAC
提示

不要被题目所欺骗,不涉及生物知识,其实很简单啦,好好理解一下。

题解
#include<bits/stdc++.h>
using namespace std;
int main()
{
    char s[300];
    cin.getline(s,300);
    for(int i=0;i<strlen(s);i++)
    {
        if(s[i]=='A')
        {
            s[i]='T';
        }
        else if(s[i]=='T')
        {
            s[i]='A';
        }
        else if(s[i]=='G')
        {
            s[i]='C';
        }
        else{
            s[i]='G';
        }
    }
    for(int i=0;i<strlen(s);i++)
    {
        cout<<s[i];
    }
    return 0;
}

问题 D: 矩阵交换行

题目描述

给定一个5×5的矩阵(数学上,一个r×c的矩阵是一个由r行c列元素排列成的矩形阵列),将第n行和第m行交换,输出交换后的结果。

输入

输入共6行,前5行为矩阵的每一行元素,元素与元素之间以一个空格分开。

第6行包含两个整数m、n,以一个空格分开(1≤m,n≤5)。

输出

输出交换之后的矩阵,矩阵的每一行元素占一行,元素之间以一个空格分开。

样例输入 
1 2 2 1 2
5 6 7 8 3
9 3 0 5 3
7 2 1 4 6
3 0 8 2 4
1 5
样例输出 
3 0 8 2 4
5 6 7 8 3
9 3 0 5 3
7 2 1 4 6
1 2 2 1 2
题解 
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int m,n;
    int matrix[6][6];
    for(int i=0;i<5;i++)
    {
        for(int j=0;j<5;j++)
        {
            cin>>matrix[i][j];
        }
    }
    cin>>m>>n;
    swap(matrix[m-1],matrix[n-1]);
    for(int i=0;i<5;i++)
    {
        for(int j=0;j<5;j++)
        {
            cout<<matrix[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

问题 E: 用递归函数输出斐波那契数列第n项

题目描述

有这样的一个数列:他的第一项为0,第二项为1,之后的每一项均为前两项之和。即如下数列:0,1,1,2,3,5,8,13...。现在给出一个整数n,请输出这个数列的第n项。

输入

一个整数n,其中1<=n<=30

输出

数列第n项的值。

样例输入 
5
样例输出 
3
题解
#include<bits/stdc++.h>
using namespace std;
int fibo(int n)
{
    if(n==1)
    {
        return 0;
    }
    else if(n==2)
    {
        return 1;
    }
    else
    {
        return fibo(n-1)+fibo(n-2);
    }
}
int main()
{
    int n;
    cin>>n;
    cout<<fibo(n);
    return 0;
}

问题 F: 递归法求Hermite多项式的值

题目描述

Hermite多项式是这样的多项式:
 


对于给定的x和正整数n,求多项式的值。

输入

两个正整数n和x,中间以空格分隔,其中0<=n<=10,0<=x<=1000

输出

一个浮点数,即多项式的值,保留两位小数

样例输入 
1 1
样例输出 
2.00
题解
#include<bits/stdc++.h>
using namespace std;
double Hermite(double n,double x)
{
    if(n==0)
    {
        return 1;
    }
    else if(n==1)
    {
        return 2*x;
    }
    else{
        return 2*x*Hermite(n-1,x)-2*(n-1)*Hermite(n-2,x);
    }
}
int main()
{
    double n,x;
    cin>>n>>x;
    printf("%.2lf",Hermite(n,x));
}

问题 G: [蓝桥杯2017初赛]兴趣小组

题目描述

为丰富同学们的业余文化生活,某高校学生会创办了3个兴趣小组(以下称A组,B组,C组)。
每个小组的学生名单分别在【A.txt】,【B.txt】和【C.txt】中。
每个文件中存储的是学生的学号。
由于工作需要,我们现在想知道:
既参加了A组,又参加了B组,但是没有参加C组的同学一共有多少人?

输入

A.txt
B.txt
C.txt

输出

输出一个整数表示答案

题解
#include<bits/stdc++.h>
using namespace std;
int main()
{
    cout<<"20";
}

问题 H: [蓝桥杯2018初赛]测试次数

题目描述

x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。
各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通。
x星球有很多高耸入云的高塔,刚好可以用来做耐摔测试。
塔的每一层高度都是一样的,与地球上稍有不同的是,他们的第一层不是地面,而是相当于我们的2楼。
如果手机从第7层扔下去没摔坏,但第8层摔坏了,则手机耐摔指数=7。
特别地,如果手机从第1层扔下去就坏了,则耐摔指数=0。
如果到了塔的最高层第n层扔没摔坏,则耐摔指数=n
为了减少测试次数,从每个厂家抽样3部手机参加测试。
某次测试的塔高为1000层,如果我们总是采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢?

输出

输出一个整数表示答案

题解
#include<bits/stdc++.h>
using namespace std;
int main()
{
   int a[5][1000];
   for(int i=1;i<=3;i++)
   {
    for(int j=1;j<=1000;j++)
    {
        a[i][j]=j;
    }
   }
   for(int j=1;j<=1000;j++)
   {
    for(int i=2;i<=3;i++)
    {
        for(int k=2;k<j;k++)
        {
            a[i][j]=min(a[i][j],max(a[i-1][k-1]+1,a[i][j-k]+1));
        }
    }
   }
    cout<<a[3][1000]<<endl;
    return 0;
}

问题 I: ACM 罚时

题目描述

ACM国际大学生程序设计竞赛是由国际计算机学会主办的,一项旨在展示大学生创新能力、团队精神和在压力下编写程序、分析和解决问题能力的年度竞赛。参赛队伍最多由三名参赛队员组成,竞赛中一般命题10-13题,试题描述为英文,比赛时间为5个小时,前4个小时可以看到实时排名,最后一小时封榜,无法看到排名。竞赛可以使用C、C++、Python和Java。重点考察选手的算法和程序设计能力,选手可携带任何非电子类资料,包括书籍和打印出来的程序等。 返回结果 AC (Accepted)表示答案正确,WA (Wrong Anwser)表示答案错误。

另外,ACM比赛有个“罚时”(Penalty)的概念,首先做的题多的队伍排名更高,做出 题目数量相同的队伍,由罚时来判断。对于一道题目,在这道题目得到 AC 之前,每一次 WA 都会计入一次“罚时”。如果该题最终也没有 AC 则该题不会产生“罚时”

现在,给出一个队伍的提交记录。里面包含了每次提交的“题目序号”以及“评测结果”。请你求出这个队伍最终通过了几题,以及得到几次“罚时”。

输入

第一行,输入两个整数,n,m,代表比赛共 n 题,队伍共提交 m 次。(1≤n≤10^5,0≤m≤10^5)
接下来 m行,每行一个整数 ai,以及一个字符串 bi ,代表第 i次提交了第 ai题,状态是 ��.
(1≤ai≤n, bi∈{"AC","WA"})

输出

输出两个整数,分别代表通过的题目数量以及得到的“罚时”数量。

样例输入 
2 5
1 WA
1 AC
2 WA
2 AC
2 WA
样例输出 
2 2
题解
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,m;
    cin>>n>>m;
    int time[n+1]={0};
    int right=0;
    int addtime[n+1]={0};
    for(int i=0;i<m;i++)
    {
        int a;
        string b;
        cin>>a>>b;
        if(time[a]==0)
        {
            if(b=="AC")
            {
                time[a]=1;
                right++;
            }
            else
            {
                addtime[a]++;
            }
        }
    }
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        if(time[i]==0)
        {
            addtime[i]=0;
        }
        sum+=addtime[i];
    }
    cout<<right<<" "<<sum;
}

问题 J: 2.4.7 集合运算

题目描述

给定N个集合,第1个集合Si有Ci个元素(集合可以包含两个相同的元素)。
集合中的每个元素都用1~10000 的正数表示。
查询两个给定元素i和j是否同时属于至少一个集合。
换句话说,确定是否存在一个数字k(1≤k≤N),使得元素i和元素j都属于Sk。

输入

输入的第1行包含一个整数N (1≤N≤1000),表示集合的数量。
第2~N+1行,每行都以数字Ci(1≤Ci≤10000)开始,后面有Ci个数字,表示该集合中的元素。
第N+2行包含一个数字Q(1≤Q≤200000),表示查询数。
接下来的Q行,每行都包含一对数字i和j(1≤i,j≤10000, i可以等于j), 表示待查询的元素。

输出

对于每个查询,如果存在这样的数字k,则输出“Yes",否则输出“No"

样例输入 
3
3 1 2 3
3 1 2 5
1 10
4
1 3
1 5
3 5
1 10
样例输出 
Yes
Yes
No
No
题解
#include<bits/stdc++.h>
using namespace std;
int main() 
{
    int N;
    cin>>N;
    vector<unordered_set<int>> sets(N);
    for (int i=0;i<N;i++) 
    {
        int Ci;
        cin>>Ci;
        for (int j=0;j<Ci;j++) 
        {
            int num;
            cin>>num;
            sets[i].insert(num);
        }
    }
    int Q;
    cin>>Q;
    for (int i = 0; i < Q; i++) 
    {
        int num1, num2;
        cin>>num1>>num2;
        bool found = false;
        for (int j=0;j<N;j++) 
        {
            if (sets[j].count(num1) && sets[j].count(num2)) 
            {
                found=true;
                break;
            }
        }
        if (found) 
        {
            cout<<"Yes"<<endl;
        } 
        else
        {
            cout<<"No"<<endl;
        }
    }
    return 0;
}

问题 K: 双刀流银色战车

题目描述

银色战车+阿努比斯神是波波仅有的高光时刻,那么波鲁纳雷夫玩节奏光剑的话会怎么样呢?
给出两个长度均为n字符串,L表示所有的左手键需要砍的字符,R表示所有的右手键需要砍的字符。
波波挥剑时遵循左-右-左-右……的顺序。
那么字符出现的顺序应该如何?

输入

1≤n

≤100
|L|==|R|==n

输出

总的字符串

样例输入 
2
ip cc
样例输出 
icpc
题解
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;
    string a,b;
    cin>>a>>b;
    for(int i=0;i<n;i++)
    {
        cout<<a[i]<<b[i];
    }
}

问题 L: 时间要开始加速了

题目描述

众所周知,屑神父一紧张会数质数。
无独有偶,小L在生气时就会从小到大连续的数正整数。
周三时,小Z因为没有将上周周赛数据导入表格,导致小L之前搞的一切都成了无用功。小L很生气,后果很严重!
这时候有n个无序正整数,小L要从左到右的将一些数从中剔除。
如果还剩下k个数,那么这k个数应该是由1到k的有序排列。
请问,小L最少需要剔除多少个数?
如果这n个数都被剔除的话,小L就不忍了!他会好好地将小Z教训一顿。相应的,输出-1。

输入

1≤n≤2∗10^5
1≤Ai≤n

输出

k或者是-1

样例输入 
6
1 1 4 5 1 4
样例输出 
5
题解
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;
    int a[n+1];
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    int x;
    int k=0;
    int index;
    for(int i=0;i<n;i++)
    {
        if(a[i]==1)
        {
            x=a[i];
            index=i;
            break;
        }
        else{
            k++;
        }
    }
    for(int i=index+1;i<n;i++)
    {
        if(a[i]-x==1)
        {
            x=a[i];
        }
        else
        {
            k++;
        }
    }
    if(k==n)
    {
        cout<<"-1";
    }
    else{
        cout<<k;
    }
}

问题 M: 2.4.9.2 双重队列

题目描述

银行的每个客户都有一个正整数标识K,到银行请求服务时将收到一个正整数优先级P。
银行经理提议打破传统,有时为优先级最低的客户服务,而不是为优先级最高的客户服务。系统将收到以下类型的请求: 
0:系统需要停止服务。 
1 K P:将客户K及其优先级P添加到等待队列中。
 2:为优先级最高的客户提供服务,并将其从等待名单中删除。
 3:为优先级最低的客户提供服务,并将其从等待名单中删除。

输入

输入的每一行都包含一个请求,只有最后一行包含停止请求(代码0)。假设在列表中包含新客户的请求时(代码1),在列表中没有统一客户的其他服务请求或有相同的优先级。标识符K小于10的6次方,优先级P小于10的7次方。客户可以多次到银行请求服务,并且每次都可以获得不同的优先级。

输出

对于代码2或3的每个请求,都单行输出所服务客户的标识符。如果请求时等待列表为空,则输出0.

样例输入 
2
1 20 14
1 30 3
2
1 10 99
3
2
2
0
样例输出 
0
20
30
10
0
题解 
//第一天写题解同学的解答
#include<bits/stdc++.h>
using namespace std;
map<int,int> a;
int main(){
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        switch(n)
        {
            case 0:
                return 0;
            case 1:
                int a1,b1;
                scanf("%d%d",&a1,&b1);
                a[b1]=a1;
                break;
            case 2:
                if(a.empty())printf("0\n");
                else{
                     
                    auto it=--a.end();
                    printf("%d\n",it->second);
                    a.erase(it);
                }
                break;
            case 3:
                if(a.empty())printf("0\n");
                else{
                    auto it=a.begin();
                    printf("%d\n",it->second);
                    a.erase(it);
                }
                break;
        }
    }
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_74367776

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值