牛客小白月赛7

2023-01-08,

A-送分题

题目描述

做水题就是在浪费时间,但是一场比赛要是没有送分的签到题,大家的比赛体验就会很差。为了优化你的比赛体验又不浪费你的读题时间,我并不打算给你很复杂的故事背景,你只需要复制下面的代码并选择正确的语言提交即可通过此题。

#include<iostream>
using namespace std;
long long f(long long n)
{
    if (n < 20180001) return n + 2017;
    return f(f(n - 2018));
}
int main()
{
    long long n;
    cin >> n;
    cout << f(n) << endl;
    return 0;
}

输入描述:

输入一个整数n。(1 ≤ n ≤ 10^18)

输出描述:

输出一个整数表示答案。

示例1

输入

20182017

输出

20182017
解题思路:暴力多试几组数据可以发现:当n<=20180000时,f(n)=n+2017;否则f(n)恒等于20182017。
AC代码:
 1 #include<iostream>
 2 using namespace std;
 3 typedef long long LL;LL n;
 4 int main(){
 5     while(cin>>n){
 6         if(n<20180001)cout<<n+2017<<endl;
 7         else cout<<20182017<<endl;
 8     }
 9     return 0;
10 }

C-谁是神射手

题目描述

有一天,MWH突然来了兴致,想和CSL比比谁枪法好。于是他们找来了一个瓶子,比比看谁先打中这个瓶子。 给定MWH的命中率α%和CSL的命中率β%。 两人轮流射击,MWH先手,问谁获胜的概率大?

输入描述:

输入两个整数α和β,表示MWH和CSL的命中率。(0≤α,β≤100).

输出描述:

若MWH获胜的概率大,则输出"MWH"。 若CSL获胜的概率大,则输出"CSL",否则输出"equal"。

示例1

输入

100 100

输出

MWH

示例2

输入

0 100

输出

CSL
解题思路:这道题和cf上的一道题很类似,思路都是一样的,链接:B - Archer。简单说一下:如果先手第n场赢,那么前n-1场的概率如图所示,累加所有情况的概率即可(有点坑,比赛时多乘了一个后手失败的概率,导致一直WA,QAQ=_=||);如果后手第n场赢,那么最后要多乘上一个先手失败的概率,再累加所有情况的概率即可。同时还要注意,如果n==0&&m!=0,那么先手必败;如果n==100,m无论为何值,先手必赢;如果n==0&&m==0,那么两者赢的概率肯定相等。最后贴一下大佬整理的公式!!!

AC代码:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     int n,m;
 5     while(cin>>n>>m){
 6         if(!n&&m)cout<<"CSL"<<endl;
 7         else if(n==100)cout<<"MWH"<<endl;
 8         else if(!n&&!m)cout<<"equal"<<endl;
 9         else {
10             double x=n*0.01*(1/(1-(1-n*0.01)*(1-m*0.01)));
11             double y=m*0.01*(1-n*0.01)*(1/(1-(1-m*0.01)*(1-n*0.01)));
12             if(x>y)cout<<"MWH"<<endl;
13             else if(x<y)cout<<"CSL"<<endl;
14             else cout<<"equal"<<endl;
15         }
16     }
17     return 0;
18 }

 E-Applese的超能力

题目描述

Applese有个神奇的能力,TA可以把m个硬币融合成1个硬币,是不是很厉害。现在Applese有n个硬币,TA想把这个n个硬币融合成1个,请问他能完成吗?

输入描述:

输入两个整数n,m(1 ≤ n, m ≤ 10^9)

输出描述:

如果Applese能完成,输出"Yes",否则输出"No"。

示例1

输入

10 7

输出

No
解题思路:用1个硬币替换m个硬币,每次操作减少了m-1个,因为最终要合并为1个硬币,所以操作下来一共减少了n-1个,如果有k次操作使得减少的个数恰为n-1,即(n-1)%(m-1)==0,前提是m!=1,如果m为1,那么合并到最后永远都不会剩下1个硬币。如果m==1&&n==1,那么最终也可以合并成1个硬币,即为"Yes"。
AC代码:
1 #include<bits/stdc++.h>
2 using namespace std;
3 int main(){
4     int n,m;
5     while(cin>>n>>m){
6         cout<<(((n==1&&m==1)||(m!=1&&(n-1)%(m-1)==0))?"Yes":"No")<<endl;
7     }
8     return 0;
9 }

 F-BFS

题目描述

Bob在学习了DFS后,自己又发明了一种新的搜(luan)索(gao)方法,叫做BFS(Bobby First Search)。
这种搜索被定义为:在一个字符串中,从前向后查找第一个子串"Bob"出现的位置。(不区分大小写)

输入描述:

输入一个不含空格的字符串S(可能含有大小写字母,数字)。(1 ≤ |S| ≤ 100)

输出描述:

输出一个数字,表示"Bob"第一次出现的位置(下标从0开始)。
如果没有出现,则输出"-1"。

示例1

输入

Bobob

输出

0

示例2

输入

bobby

输出

0

示例3

输入

BFS

输出

-1
解题思路:将源字符串中所有大写字母改成小写字母,然后使用string.find()函数即可找到子串"bob"出现的第一个位置,如果源字符串不包含子串"bob"即pos==string::npos,此时输出-1即可。
AC代码:
 1 #include<iostream>
 2 using namespace std;
 3 string str;
 4 int main(){
 5     while(cin>>str){
 6         for(int i=0;str[i];++i)
 7            if(isupper(str[i]))str[i]+=32;
 8         size_t pos=str.find("bob");
 9         if(pos!=string::npos)cout<<pos<<endl;
10         else cout<<-1<<endl;
11     }
12     return 0;
13 }

G-CSL分苹果

题目描述

CSL手上有n个苹果,第i个苹果的质量是wi,现在他想把这些苹果分给他的好朋友wavator和tokitsukaze。但是CSL为了不让他们打架,根据质量决定尽量地均分成两堆分给他们。现在CSL想知道到底给每个人分多少质量的苹果。
注意:苹果不能劈开来,并且如果不能正好均分,tokitsukaze小姐姐会拿到重的那一堆。

输入描述:

第一行输入一个整数n(2 ≤ n ≤ 100),第二行n个整数,表示每个苹果的质量wi(1 ≤ wi ≤ 100)。

输出描述:

输出两个整数,分别表示wavator和tokitsukaze得到的苹果的质量。

示例1

输入

3
2 2 2

输出

2 4
解题思路:01背包,数据比较小,不用优化直接暴力!!!
AC代码:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,sum,wi[105],dp[10005];
 4 int main(){
 5     while(~scanf("%d",&n)){
 6         sum=0;
 7         memset(dp,0,sizeof(dp));
 8         for(int i=0;i<n;++i){
 9             scanf("%d",&wi[i]);
10             sum+=wi[i];
11         }
12         for(int i=0;i<n;++i)
13             for(int j=sum/2;j>=wi[i];--j)
14                 dp[j]=max(dp[j],dp[j-wi[i]]+wi[i]);
15         printf("%d %d\n",dp[sum/2],sum-dp[sum/2]);
16     }
17     return 0;
18 }

I-新建 Microsoft Office Word 文档

题目描述

CSL正在学习《计算机办公自动化》文件的建立与删除。
CSL发现,当他新建一个word文档时,会得到一个名为"新建 Microsoft Office Word 文档.doc"的文件,再新建一个,则名为"新建 Microsoft Office Word 文档(2).doc",再新建,便是"新建 Microsoft Office Word 文档(3).doc"。不断新建,编号不断递增。倘若他已经新建了三个文档,然后删除了"新建 Microsoft Office Word 文档(2).doc",再新建一个就又会得到一个"新建 Microsoft Office Word 文档(2).doc"。
严格来说,Windows在每次新建文档时,都会选取一个与已有文件编号不重复的最小正整数作为新文档的编号。
现在,请你编程模拟以上过程,支持以下两种操作:
New:新建一个word文档,反馈新建的文档的编号;
Delete id:删除一个编号为id的word文档,反馈删除是否成功。
初始时一个文件都没有,"新建 Microsoft Office Word 文档.doc"的编号算作1。

输入描述:

第一行一个正整数n表示操作次数,接下来n行,每行表示一个操作。若该行为"New",则表示新建,为:Delete id"则表示要删除编号为id的文档,其中id为一个正整数。操作按输入顺序依次进行。操作次数不超过100000,删除编号的数值不超过100000。

输出描述:

对于输入的每一个操作,输出其反馈结果。对于新建操作,输出新建的文档的编号;对于删除操作,反馈删除是否成功:如果删除的文件存在,则删除成功,输出"Successful",否则输出"Failed"。

示例1

输入

12
New
New
New
Delete 2
New
Delete 4
Delete 3
Delete 1
New
New
New
Delete 4

输出

1
2
3
Successful
2
Failed
Successful
Successful
1
3
4
Successful
解题思路:用优先队列最小堆维护一下最小未使用的编号,做个标记即可。时间复杂度为O(nlogn)。
AC代码:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn=100005;
 5 int n,q,u[maxn];string obj;
 6 priority_queue<int,vector<int>,greater<int> > que;//最小堆
 7 int main(){
 8     while(cin>>n){
 9         memset(u,0,sizeof(u));
10         while(!que.empty())que.pop();
11         for(int i=1;i<=n;++i)que.push(i);
12         for(int i=1;i<=n;++i){
13             cin>>obj;
14             if(obj=="New"){
15                 u[que.top()]=1;
16                 cout<<que.top()<<endl;
17                 que.pop();
18             }
19             else {
20                 cin>>q;
21                 if(u[q])u[q]=0,que.push(q),cout<<"Successful"<<endl;
22                 else cout<<"Failed"<<endl;
23             }
24         }
25     }
26     return 0;
27 }