Codeforces Round #531 (Div. 3)

http://codeforces.com/contest/1102

这场比赛的A题是个小思维题,连续的四个数x,x+1,x+2,x+3,则x+(x+3)=(x+1)+(x+2),所以从n开始考虑,每四个数恰好分配,最后只会剩下n%4个数,只需要简单算一下判断一下就ok,

B题略坑。。比赛的时候题意读了很久都读不懂。就先做C了。快一个小时了才又给的题意解释,勉强算是明白了,感觉倒不是难题,然而,,B题莫名又T了一发,,RE了两发,。,改了感觉并不重要的地方,换换语言,感觉代码本质没变,,然后A了,,,也真是佩服自己敢交的勇气,,,超怕被hack。。。

代码:

#include<bits/stdc++.h>
using namespace std;
int n,k,ok,vis[5055],ans[5055];
struct AA
{
    int x,rt;
    bool operator<(const AA &aa)const
    {
        return x<aa.x;
    }
}pos[5055];
int main()
{//cout<<"!"<<endl;
    scanf("%d%d",&n,&k);

    for(int i=1;i<=n;i++)
    {
        pos[i].rt=i;
        scanf("%d",&pos[i].x);
        if(++vis[pos[i].x]>k) ok=1;
    }
    if(ok==1)
    {
        printf("NO\n");
        return 0;
    }
     printf("YES\n");
    sort(pos+1,pos+n+1);
    for(int i=1;i<=n;i++)
    {
        if((i%k)==0)
        ans[pos[i].rt]=k;
        else ans[pos[i].rt]=(i%k);
    }
    for(int i=1;i<=n;i++)
         printf("%d ",ans[i]);
    printf("\n");
    return 0;
    /*
    if(ok)

    else
    cout<<"NO"<<endl;
        */
}

C题小思维,跟x与y的大小有关,因为进行次数相当于无限多次,所以x>y的时候一定所有都碎了,x<=y的时候,x只能破坏<=x的门,不然y能救回来,,而且在x破坏<=x的门的后,y可以修复一扇<=x的门,这样就能多保住一扇。

代码:

#include<bits/stdc++.h>
using namespace std;
int n,x,y,m,ok,a[100005],ans;
int main()
{
    scanf("%d%d%d",&n,&x,&y);

    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    if(x>y)
    {
        cout<<n<<endl;
        return 0;
    }
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++)
    {
        if(a[i]<=x) ans++;
        else break;
    }

        int i;
        for(i=1;i<ans;i++)
        {
            a[ans]+=y;
            if(a[ans]>x) ans--;
        }
            cout<<ans<<endl;

    /*
    if(ok)
    cout<<"YES"<<endl;
    else
    cout<<"NO"<<endl;
        */
}

D题也比较简单,就是先算一下0,1,2的数量,多于平均数t一定得转化成少于平均数的数,从前往后遍历,0的前t个0保持不变,然后后面若还有多余的0,就看看1够不够,变成1,1够了,就只能变成2,

1就是先看有没有多余的需要变成0的,然后安排1本身,最后再有多余的变成2,

2就是,2若多余,若0少,先变成0,然后1若少,变成1,最后保留为自己。

代码:

就暴力写 了,没注意美观了,,,还因为每加else if的elseWA了一发,,,也怪自己没试样例。。

#include<bits/stdc++.h>
using namespace std;
int n,a[10],t,b[10];
string s;
int main()
{//cout<<"!"<<endl;
    cin>>n>>s;
    t=n/3;
    for(int i=0;i<n;i++)
    {
        a[s[i]-'0']++;
    }
    for(int i=0;i<n;i++)
    {
        if(s[i]=='0')
        {
            if(b[0]<t) {b[0]++;continue;}
            else if(b[0]>=t)
            {
                if(a[1]<t)
                {//cout<<i<<" "<<a[1]<<" "<<a[2]<<" "<<t<<"!"<<endl;
                    a[1]++;a[0]--;
                    b[1]++;
                    s[i]='1';
                }
                else
                {
                    a[2]++;a[0]--;
                    b[2]++;
                    s[i]='2';
                }
            }
        }
       else  if(s[i]=='1')
        {
            if(a[1]>t&&a[0]<t)
            {
                s[i]='0';
                a[0]++;
                b[0]++;
                a[1]--;
                continue;
            }
            if(b[1]<t) {b[1]++;continue;}
            else if(b[1]>=t)
            {
                a[2]++;a[1]--;
                b[2]++;
                s[i]='2';
            }
        }
       else  if(s[i]=='2')
        {
            if(a[2]>t&&a[0]<t)
                {
                    a[0]++;a[2]--;
                    b[0]++;
                    s[i]='0';
                    continue;
                }
                else if(a[2]>t&&a[1]<t)
                {
                    a[1]++;a[2]--;
                    b[1]++;
                    s[i]='1';
                    continue;
                }
            if(b[2]<t) {b[2]++; continue;}
        }
    }
    cout<<s<<endl;

    /*
    if(ok)

    else
    cout<<"NO"<<endl;
        */
}
/*

*/

最后拼了几分钟写了个E题,又是快速幂粗心。。。没考虑0次方的情况。导致快速幂里死循环了,,T了一发。。

思路倒是也不难,就是找间断点,可以选择是否变化的点的个数,然后2的ans次方。。。就完了,倒不是难题,

思路:根据题意要求b又要递增,又要与a对应的相等的点相等,那么a中相等的点及其中间夹的所有点的值在b中都相等。与中间点a值相等的点在b中也要相同,,,所以就是循环下去,一直结束,就是一个间断点,再就是注意,最后一个数后面不能是间断点就可以了,,,

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mod 998244353
int n,a[500005];
ll ans;
ll POW(ll aa,ll bb)
{
    if(bb==0) return 1;
    if(bb==1) return aa%mod;
    if(bb%2) return POW(aa*aa%mod,bb/2)*aa%mod;
    else  return POW(aa*aa%mod,bb/2);
}
int main()
{    //cout<<POW(2,200005)<<endl;
    scanf("%d",&n);
    map<int,int>ma;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        ma[a[i]]=i;
    }
    for(int i=1;i<n;)
    {
        for(int j=i;j<=i;j++)
        {
            i=max(i,ma[a[j]]);
        }
        if(i<n)
        {
            ans++;
        }
        i++;

    }

    ans=POW(2,ans);
    printf("%I64d\n",ans%mod);
}

 

 

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值