2019.11.16工作坊比赛题解

Posted algonote

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019.11.16工作坊比赛题解相关的知识,希望对你有一定的参考价值。

A

https://vjudge.net/contest/343173#problem/A

把所有的长条按长度进行排序

在从左到右扫一遍能构造出的矩形,其中所有矩形中Max(Width,Height)的最大值即为能够造出的最大正方形的边长

#include <cstdio>
#include <algorithm>
using namespace std;
int t,n,a[1001],ans;
bool cmp(int a,int b) {
    return a>b;
}
int main()
{
    scanf("%d",&t); 
    while(t--)
    {
        ans=0;
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        sort(a+1,a+n+1,cmp);
        for (int i=1;i<=n;i++) ans=max(ans,min(i,a[i]));
        printf("%d
",ans);
    }
} 

 

B

https://vjudge.net/contest/343173#problem/B

可行的只有三种情况,即a==b,a+1==b,a==9&&b==1,针对这三种情况各写一个可行解的模板即可

#include <cstdio>
#include <algorithm>
using namespace std;
int a,b;
int main()
{
    scanf("%d%d",&a,&b);
    if (b==a)
        printf("%d0 %d1
",a,b);
    else
        if (b==a+1)
            printf("%d %d
",a,b);
        else
            if (b==1&&a==9)
                printf("%d %d0
",a,b);
            else
                printf("-1
");
} 

 

C

https://vjudge.net/contest/343173#problem/C

能力值相邻的人不能分配到同一组

考虑到如果把所有偶数能力值分配在一组,把所有奇数能力值分配在一组,肯定满足题目要求,所以可以得出组数一定<=2

那么只要把所有人按能力值排序,从左到右扫一次判断这些人能不能在同一组就知道答案是1还是2了

#include <cstdio>
#include <algorithm>
using namespace std;
int q,n,a[101],ans;
int main()
{
    scanf("%d",&q);
    while(q--)
    {
        ans=1;
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        sort(a+1,a+1+n);
        for (int i=1;i<n;i++) if (a[i]==a[i+1]-1) ans=2;
        printf("%d
",ans);
    }
} 

 

D

https://vjudge.net/contest/343173#problem/D

求满足n=(2^a1+p)+(2^a2+p)+...+(2^ak+p)的k的最小值

对等式进行变形

n-p*k=2*a1+2*a2+...+2*ak

把n-p*k分解为若干个2^ai的和

对于1可以分解为1,最多一种分法

对于10可以分解为10或1+1,最多两种分法

对于100可以分解为100或10+10或10+1+1或1+1+1+1,最多四种分法

所以组合起来,对于n-p*k,最少分解为countbit(n-p*k)个2^ai的和,最多分解为n-p*k个2^ai的和

已知countbit<=32所以如果对i=33满足,那么对i=32肯定也满足,所以答案小于等于32,这样就减小了搜索的范围

#include <cstdio>
int n,p,b,ans=-1;
int countbit(int x)
{
    int r=0;
    while(x)
    {
        r+=x%2;
        x>>=1;
    }
    return r;
}
int main()
{
    scanf("%d%d",&n,&p);
    for (int i=0;i<=32;i++)
    {
        int t=n-p*i;
        if (ans==-1&&t>=i&&i>=countbit(t)) ans=i;
    }
    printf("%d",ans);
}

 

E

https://vjudge.net/contest/343173#problem/E

田忌赛马,尽可能多赢的就可以了

对于赢不了的情况不要着急做决定,应该先跳过,否则可能会浪费后面本来能赢的机会

等所有能赢的情况都统计完了之后,再决定之前跳过的情况是输还是平手

#include <cstdio>
int t,n,a,b,c;
char s,ans[101],win;
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        win=0;
        scanf("%d%d%d%d",&n,&a,&b,&c);
        for (int i=1;i<=n;i++) ans[i]=0;
        scanf("%c",&s);
        for (int i=1;i<=n;i++)
        {
            scanf("%c",&s);
            if (s==R&&b>0) {ans[i]=P;b--;win++;}
            if (s==P&&c>0) {ans[i]=S;c--;win++;}
            if (s==S&&a>0) {ans[i]=R;a--;win++;}
        }
        for (int i=1;i<=n;i++)
        {
            if (ans[i]==0)
            {
                if (a>0) {ans[i]=R;a--;continue;}
                if (b>0) {ans[i]=P;b--;continue;}
                if (c>0) {ans[i]=S;c--;continue;}
            }
        }
        if ((n%2==1&&win>=(n+1)/2)||(n%2==0&&win>=n/2))
        {
            printf("YES
");
            for (int i=1;i<=n;i++) printf("%c",ans[i]);
            printf("
");
        }
        else
        {
            printf("NO
");
        }
    }
}

 

以上是关于2019.11.16工作坊比赛题解的主要内容,如果未能解决你的问题,请参考以下文章

codeforces比赛后怎么看题解和答案

codeforces比赛后怎么看题解和答案

CF Round #631 题解

两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。 已抽签决定比赛名单。有人向队员打听比赛的名单。 a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。(代码片段

OCAC暑期比赛第一场 J题 星球语言的翻译 题解

牛客2021年愚人节比赛 题解