Codeforces Round #606 D

别等时光非礼了梦想. 提交于 2019-12-16 20:51:46

题意

大概是01串接龙,接的时候必须尾首相同。
你可以将其中的串反转,使得最后拼起来但要保证最后没有相同的。

题解

首先可以想到
真正有用的是首尾,单独拿出来可以发现只有四种状态。记录一下即可。
如果00和11都在的话,
连接的就只有00 0110 0110 01 11.这是我一开始想到的。
也就是奇数个。但实际上:00 01 11 11 11 10 01 10 01
这样无论奇数偶数都可以。

我们计算出01和10的个数相加,除以2,会存在有一个会多一个。
对于这种情况我们可以发现,不论是哪种情况多出来的一定是01。

相反以11作开头也是如此。多出来则是10。

分别考虑只有00没有11,只有11没有00.
这里我是没有考虑到的,因为一开始我只想到了00 0110 0110的顺序,所以这样子01一定是多的那个。但是实际上也可以,10 00 0110 0110,也就是10也可以是多的那个。就需要计算两次。

11的情况是类似的。

最后只剩下只有01 10的这个就是计算两次即可。因为两个都可以做多的那个。

因为需要计算多次,写一个函数即可(00和11都在的情况需要特判没有01和10.)

【注意考虑不选会导致重复的,具体做法是开个map判断一下】

#include<bits/stdc++.h>
using namespace std;

string str[200050];
int cnt[4];
vector<int>G[4];
vector<int>T,tmp;
map<string,int>mp;
int ans;

int inv(int id){
    if(id==1)return 2;
    if(id==2)return 1;
}

void del(int id,int flag){
    int num=cnt[1]+cnt[2];
    if(flag==1&&num==0)return ;
    int ttt;
    tmp.clear();
    if(abs(cnt[id]-num/2)<ans){
        bool ok=true;
        ttt=abs(cnt[id]-num/2);
        if(cnt[id]>num/2){
            if(ttt<=G[id].size()){
                for(int i=1;i<=ttt;i++)tmp.push_back(G[id][i-1]);
            }
            else ok=false;
        }
        else{
            if(ttt<=G[inv(id)].size()){
                for(int i=1;i<=ttt;i++)tmp.push_back(G[inv(id)][i-1]);
            }
            else ok=false;
        }
        if(ok)ans=ttt,T=tmp;
    }
}

int main(){
     int Time;cin>>Time;
     while(Time--){
        int n;cin>>n;
        for(int i=0;i<4;i++)G[i].clear();
        memset(cnt,0,sizeof(cnt));
        mp.clear();
        for(int i=1;i<=n;i++){
            cin>>str[i];mp[str[i]]=1;
        }
        for(int i=1;i<=n;i++){
            int val=2*(str[i][0]-'0')+str[i][str[i].size()-1]-'0';
            cnt[val]++;
            reverse(str[i].begin(),str[i].end());
            if(!mp[str[i]])G[val].push_back(i);
        }
        ans=0x3f3f3f3f;T.clear();
        if(cnt[0]||cnt[3]){
            if(cnt[0]){
                if(cnt[3])del(2,1);
                else del(2,0),del(1,0);
            }
            if(cnt[3]){
                if(cnt[0])del(1,1);
                else del(1,0),del(2,0);
            }
        }
        else{
            del(1,0);
            del(2,0);
        }
        if(ans==0x3f3f3f3f){
            puts("-1");
            continue;
        }
        cout<<ans<<endl;
        for(int i=1;i<=ans;i++)printf("%d ",T[i-1]);puts("");
     }
}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!