Codeforces Round #322 (CF 581 ABCD)题解

8 篇文章 0 订阅
8 篇文章 0 订阅

打的一片渣渣啊。。。各种低级错误

代码能力还是欠缺不少

前四个题没有什么复杂的算法,后两个还没看

A:水题    3min过

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<algorithm>
#include<cstdlib>

#define maxn 201314
#define inf 0x3f3f3f3f
#define LL long long

using namespace std;
int a,b;
int main()
{
    cin>>a>>b;
    if(a>b)
    {
        int tmp=b;
        b=a;
        a=tmp;
    }
    //a<=b
    int t=b-a;
    int ans1=0;
    int ans2=0;
    if(t)
    {
        ans1=a;
        ans2=t/2;
    }
    else
    {
        ans1=a;
        ans2=0;
    }
    cout<<ans1<<" "<<ans2<<endl;
}


B:

给一个序列,要求对每个元素操作:如果在其后有比它大的,求出最少加上几能够使得其比其后所有元素严格大。对每个元素操作都是独立事件,并不涉及后面的元素询问

好吧题意说的有点乱。。

其实就是维护一个后缀q[n]来存储第i位之后的最大值,然后再遍历查询,O(N),但是要注意的是,q[i]是存储,在i位之后的最大值,不能包括第i位,我最开始包括了第i位,最后居然能过了pretest,真是迷醉

当然之后就被hack了

这是个很脑残的错误

code:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<algorithm>
#include<cstdlib>

#define maxn 201314
#define inf 0x3f3f3f3f
#define LL long long

using namespace std;
int n;
int q[100010];
int ans[100010];
int p[100010];
int main()
{
    cin>>n;

    for(int i=0;i<=n;i++)
    {
        p[i]=-1;
    }

    for(int i=0;i<n;i++)
    {
        scanf("%d",&q[i]);
    }
    for(int i=n-2;i>=0;i--)
    {
        if(i==n-2)p[i]=q[i+1];
        else {
        p[i]=max(p[i+1],q[i+1]);
        }
    }
    for(int i=0;i<n;i++)
    {
        if(p[i]>=q[i]){
            ans[i]=(p[i]-q[i]+1);
        }
        else
            ans[i]=0;
        printf("%d",ans[i]);
        if(i<n-1)
        {
            printf(" ");
        }
        else
            cout<<endl;
    }
}

C:

点技能点

你有n个技能,每个技能的熟练度在1-100之间,闭区间。现在这n个技能都有个初始值,你又有k个技能点可以给他们分配。rating值是这么计算的:对每个技能,将其熟练度除以10,向下取整,每个技能的这个值加和。
现在要求你合理分配技能点,使分配后的rating最高。

求每个技能对10取余的余数,余数越接近10,就优先加技能点,用这个原则扫一遍。

给他们加一圈技能点之后如果还剩下技能点,就需要做一个判断:有可能把所有技能点都加上去也不会超过100的限制,这时候就尽情加吧。。。也有可能直接都加上去就会导致超过限制,这时候就直接加满所有技能即可,做一个比较就可以了。这个判断见于代码后半部分,写了个注释的位置。

但是还有个细节要处理,就是初值全都是100的情况,最好是想办法特判,就是跳过而不是继续加技能点。。


别的没什么了,思路别乱就能写好

code :

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<algorithm>
#include<cstdlib>

#define maxn 201314
#define inf 0x3f3f3f3f
#define LL long long

using namespace std;
struct node
{
    int a;
    int m;
};
int n,k;
int sum=0;
node q[100010];
int s[100010];
bool cmp(node p,node q)
{
    return p.m<q.m;
}
int main()
{
    scanf("%d%d",&n,&k);
    int ans=0;
    int anss=0;
    for(int i=0; i<n; i++)
    {
        scanf("%d",&q[i].a);
        q[i].m=(10-(q[i].a)%10);
        ans+=(q[i].a/10);
        if(q[i].a==100)continue;
        //sum+=q[i].a;
        anss+=(100-(((q[i].a/10)*10)+10));
    }
    anss/=10;
    sort(q,q+n,cmp);
    int i=0;
    while(k)
    {
        if(k>=q[i].m)
        {
            if(q[i].a==100)
            {
                i++;
                if(i==n)break;
                else continue;
            }
            k-=q[i].m;
            ans++;
        }
        if(k)
            i++;
        if(i==n)break;
    }
    if(k)//this is used to deal with the points remained unused.
    {
        int tmp1=k/10;
        int tmp2=anss;
        ans+=min(tmp1,tmp2);
    }
    printf("%d\n",ans);
}

D:

有三个矩形logo,给出他们的尺寸,问能不能拼成一个正方形,矩形可以横放也可以竖着放。

这个题意多简洁!

然而代码很不好写。。。我写了226行。。。不知道有没有简洁方法。

我是暴力写的:检索每个边,如果能构成正方形,那么大正方形边长一定是这三个logo的边长最大值m。

以这个值为关键来搜索这三个logo,某一边长达到这个最大值m的,直接摆好就行

没有达到的,根据没有达到的logo数目,再搜索,如果有且仅有一个logo,它的两个边长都没有达到最大值m,那么这个大正方形一定拼不出来,这个不难想

如果有且仅有两个,则又要判断了,语言表示起来挺简单:如果这个大正方形能拼出来,这两个小的一定有某边长相等,这个对应题目的测试样例2,就是A和C并排的情况。

此外,即使存在某边长相等,又得看另外两边之和是否为m,只有这样才能保证拼出来是正方形

拼好之后再次检查两边长是否是相等的,都应该是m,若不是,答案仍是无解,输出-1

恩,我用了最笨的写法来实现他们

还有,代表三个logo的A,B,C是不能随意换的,输入中的第一个logo必须用A表示。。另两个同理。

赛后过的。。比赛时很难把这个过了。。

code:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<algorithm>
#include<cstdlib>

#define maxn 201314
#define inf 0x3f3f3f3f
#define LL long long

using namespace std;
int j,k,l,pre,num;
struct node
{
    int x,y,index;
}s[3];
int q[6];
char sr[110][110];
int vis[3];
int main()
{
    int ans=0;
    int m=-1;
    for(int i=0; i<6; i++)
    {
        cin>>q[i];
        m=max(m,q[i]);
    }
    s[0].x=q[0];s[0].y=q[1];s[0].index=0;
    s[1].x=q[2];s[1].y=q[3];s[1].index=1;
    s[2].x=q[4];s[2].y=q[5];s[2].index=2;
    vis[0]=vis[1]=vis[2]=0;
    j=k=l=pre=ans=0;
    num=3;
    bool flag=true;
    for(int i=0; i<3; i++)
    {
        if(s[i].x==m&&s[i].y==m)
        {
            flag=false;
            ans=-1;
        }
        else if(s[i].x==m||s[i].y==m)
        {
            num--;
            ans=m;
            vis[i]=1;
            for(j=pre; j<pre+min(s[i].x,s[i].y); j++)
            {
                for(k=0; k<m; k++)
                {
                    sr[j][k]=char(s[i].index+65);
                }
            }
            pre=j;
        }
    }
    if(num==0)
    {
        if(j!=m)
        {
            flag=false;
            ans=-1;
        }
    }
    if(!flag)
    {
        cout<<ans<<endl;
    }
    else
    {
        if(num)
        {

            if(num==1)
            {
                ans=-1;
            }
            else
            {
                node o[2];
                int t=0;
                for(int i=0; i<3; i++)
                {
                    if(vis[i]==0)
                    {
                        o[t].x=s[i].x;
                        o[t].y=s[i].y;
                        o[t].index=s[i].index;
                        t++;
                    }
                }
                if(o[0].x==o[1].y)
                {
                    if(o[0].y+o[1].x==m)
                    {
                        for(j=pre; j<pre+o[0].x; j++)
                        {
                            for(k=0; k<o[0].y; k++)
                            {
                                sr[j][k]=(char)(o[0].index+65);
                            }

                            for(k; k<m; k++)
                            {
                                sr[j][k]=(char)(o[1].index+65);
                            }

                        }
                        if(j!=m)
                        {
                            ans=-1;
                        }
                        else ans=m;
                    }
                    else
                    {
                        ans=-1;
                    }
                }
                else if(o[0].x==o[1].x)
                {
                    if(o[0].y+o[1].y==m)
                    {
                        for(j=pre; j<pre+o[0].x; j++)
                        {
                            for(k=0; k<o[0].y; k++)
                            {
                                sr[j][k]=(char)(o[0].index+65);
                            }
                            for(k; k<m; k++)
                            {
                                sr[j][k]=(char)(o[1].index+65);
                            }
                        }
                        if(j!=m)
                        {
                            ans=-1;
                        }
                        else ans=m;
                    }
                    else
                    {
                        ans=-1;
                    }
                }
                else if(o[0].y==o[1].x)
                {
                    if(o[0].x+o[1].y==m)
                    {
                        for(j=pre; j<pre+o[0].y; j++)
                        {
                            for(k=0; k<o[0].x; k++)
                            {
                                sr[j][k]=(char)(o[0].index+65);
                            }
                            for(k; k<m; k++)
                            {
                                sr[j][k]=(char)(o[1].index+65);
                            }
                        }
                        if(j!=m)
                        {
                            ans=-1;
                        }
                        else ans=m;
                    }
                    else
                    {
                        ans=-1;
                    }
                }
                else if(o[0].y==o[1].y)
                {
                    if(o[0].x+o[1].x==m)
                    {
                        for(j=pre; j<pre+o[0].y; j++)
                        {
                            for(k=0; k<o[0].x; k++)
                            {
                                sr[j][k]=(char)(o[0].index+65);
                            }
                            for(k; k<m; k++)
                            {
                                sr[j][k]=(char)(o[1].index+65);
                            }
                        }
                        if(j!=m)
                        {
                            ans=-1;
                        }
                        else ans=m;
                    }
                    else
                    {
                        ans=-1;
                    }
                }
                else
                {
                    ans=-1;
                }
            }
        }
        if(ans==-1)
        {
            cout<<ans<<endl;
        }
        else
        {
            cout<<ans<<endl;
            for(int i=0; i<m; i++)
            {
                for(int j=0; j<m; j++)
                {
                    printf("%c",sr[i][j]);
                }
                cout<<endl;
            }
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值