工作坊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\n",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\n",a,b);
    else
        if (b==a+1)
            printf("%d %d\n",a,b);
        else
            if (b==1&&a==9)
                printf("%d %d0\n",a,b);
            else
                printf("-1\n");
} 

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\n",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\n");
            for (int i=1;i<=n;i++) printf("%c",ans[i]);
            printf("\n");
        }
        else
        {
            printf("NO\n");
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/algonote/p/11871136.html