2020年ACM团队新生第一次周赛题解

A、王学姐去上学啦

二分法的模板题,大家先点下面的链接学习一下二分法。
https://www.cnblogs.com/cs-whut/p/11212022.html

这是我一年前(整整一年,2019年的10月24号hhh)学完二分之后写的学习笔记,有点丑,但是网上找不到什么好的博客…

https://fanfansann.blog.csdn.net/article/details/102726708

在这里插入图片描述

#include<iostream>
#include<algorithm>
using namespace std;
int n,k;
int a[100007];
int main()
{
	cin>>n>>k;
	for(int i=1;i<=n;i++)
	cin>>a[i];//正常读入
	int l=0,r=1e8+1,m;//r=100000001
    	//l是能取到的最小值(所以是0,也方便最后直接输出,而不要一堆代码特判),r是绝对取不到的值
	while(l+1<r)//模板
	{
		m=(l+r)/2;
		int cnt=0;//以m为长度能够切出木板的段数
		for(int i=1;i<=n;i++)
		cnt+=a[i]/m;//c++自带整除,也可以用floor
        	//枚举每段木材能切出多少木板
		if(cnt>=k)l=m;//切得多或刚好等于,则说明还有可能长度更长
		else r=m;//切得少,说明长度太大了
	}
	cout<<l<<endl;//l为答案
	return 0;
}

B、乒乓球赛制之谜

题解可以看这个博客:
https://www.luogu.com.cn/blog/hw1462633109/solution-p1042

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<math.h>
#include<vector>
#define ls (p<<1)
#define rs (p<<1|1)
#define mid (l+r)/2
#define over(i,s,t) for(register long long i=s;i<=t;++i)
#define lver(i,t,s) for(register long long i=t;i>=s;--i)
//#define int __int128
using namespace std;
typedef long long ll;//全用ll可能会MLE或者直接WA,试着改成int看会不会A
const ll N=750007;
const ll INF=1e10+9;
const ll mod=2147483647;
const double EPS=1e-10;//-10次方约等于趋近为0
const double Pi=3.1415926535897;
ll n,m,a[N];
char ch;
char s[N];
ll ansa,ansb,tot;
int main()
{
while(scanf("%c",&ch)&&ch!='E')
{
if(ch=='W')ansa++,s[tot++]=ch;
if(ch=='L')ansb++,s[tot++]=ch;
if((ansa>=11||ansb>=11)&&abs(ansa-ansb)>=2)
{
printf("%lld:%lld\n",ansa,ansb);
ansa=0;
ansb=0;
}
}
printf("%lld:%lld\n\n",ansa,ansb);
ansa=0,ansb=0;
over(i,0,tot-1)
{
if(s[i]=='W')ansa++;
if(s[i]=='L')ansb++;
if((ansa>=21||ansb>=21)&&abs(ansa-ansb)>=2)
{
printf("%lld:%lld\n",ansa,ansb);
ansa=0;
ansb=0;
}
}
printf("%lld:%lld\n",ansa,ansb);
return 0;
}

C、我们一起打牌吧

这是一道博弈的问题
我方要想取得获胜就必须在我方摸完牌之后给对方创造一个必输的局面,对于摸牌的一方,只要摸到最后在我方摸完牌之后让牌只剩下(m+1)张,
那么对方就一定输,因为对方最少也要摸走一张牌,这样就只剩下m张牌了,我方摸完就获胜了

所以结论1:必胜条件就是我方摸完牌之后最后还剩下m+1张牌

所以如果牌的总量是(m+1)的倍数,那么先手方无论如何都会输,因为摸到最后一定是对方先让牌只剩m+1张,举个例子,桌子上一共有2*(m+1)张牌,我方摸x张牌
1<=x<=m,那么对方就只摸m+1-x张牌,让牌只剩下m+1张,1<=m+1-x<=m是显然的,所以随便怎么摸,一定是对方掌握比赛权

所以如果牌不是m+1的倍数,那么先手方必然获胜

所以结论就是一共n张牌 如果n%(m+1)==0 先手摸牌的一方输,如果n%(m+1)!=0,后手摸牌的一方输

#include<iostream> 
using namespace std; 
int n,m; 
int main() 
{ 
 	while(scanf("%d%d", &n, &m) != EOF){
 	 	if(n%(m+1)!=0) printf("A Wei Win!\n");
	  	else printf("Jie Jie Win!\n");
    }
	 return 0;
}

D、铺地毯

我们可以有一些投机取巧,因为,是看特定的某个位置上最后一块覆盖了的地毯。所以说,你可以从最后一个输入的数据开始排查,如果说你找到了这个点上面有地毯,那么就直接输出这个值,如果没找到就按照题干的意思输出-1。

#include<bits/stdc++.h>
using namespace std;
int s[10000][10];
int main()
{
    int n,x,y;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=4;j++)
            cin>>s[i][j];
    }
    cin>>x>>y;
    for(int i=n;i>=1;i--)
    {
        if(s[i][1]<=x&&s[i][2]<=y&&s[i][1]+s[i][3]>=x&&s[i][2]+s[i][4]>=y)
        {
            cout<<i<<endl;
            return 0;
        }
    }
    cout<<"-1"<<endl;
    return 0;
}

E、阿洁的签到题

由题意,本别把小写字母,大写字母,数字,其他字符各用一个字符串进行保存并统计各种类型出现的次数,最后分别输出

#include <iostream>
#include<cstring>
using namespace std;
int main(){
    int i,a=0,b=0,c=0,d=0,sum=0;
    char s[10005],p[4][1001];
    cin>>s;
    for(i=0;i<strlen(s);i++){
        if(s[i]>='a'&&s[i]<='z') p[0][a++]=s[i];
        else if(s[i]>='A'&&s[i]<='Z') p[1][b++]=s[i];
        else if(s[i]>='0'&&s[i]<='9') p[2][c++]=s[i];
        else p[3][d++]=s[i];
    }
    if(a!=0) sum++;
    if(b!=0) sum++;
    if(c!=0) sum++;
    if(d!=0) sum++;
    cout<<"password level:"<<sum<<endl;
    if(a!=0)cout<<p[0]<<endl;
    else cout<<"(Null)"<<endl;
    if(b!=0)cout<<p[1]<<endl;
    else cout<<"(Null)"<<endl;
    if(c!=0)cout<<p[2]<<endl;
    else cout<<"(Null)"<<endl;
    if(d!=0)cout<<p[3]<<endl;
    else cout<<"(Null)"<<endl;
    return 0;
}



F、三份叉烧饭

#include<stdio.h>
int main()
{
	int n,t;
    long long int a,b,c;
    scanf("%d",&t);
    while(t--)
	{
	 scanf("%lld%lld%lld",&a,&b,&c);
	 printf("%lld\n",(a+b+c)/2);
    }
	return 0;
 }
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页