[Agc001D] Arrays and Palindrome

Posted wxjor

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Agc001D] Arrays and Palindrome相关的知识,希望对你有一定的参考价值。

[Agc001D] Arrays and Palindrome

题目大意:
给定一个和为(N)的序列(a),其中(a)可以任意排列。表示这个字符串的前(a_1)个字符,(a_1)个字符后面(a_2)个字符,(a_1+a_2)个字符后面(a_3)个字符以此类推所组成的字符串为回文串。
求一个作用和(a)相同的数组(b),使得加上(b)这个限制后满足条件的字符串只有字符全相同的字符串。

试题分析

所有字符一样,肯定是一眼并查集。
然后我们有数组(a),可以得到如下图之类的样子:
技术分享图片

那么仔细分析这个a数组要怎么排列才合法,因为最后肯定只有一个集合,也就意味着a数组连完之后所有这些块最后都要连起来。
简单举几个例子可以发现,奇数始终会将一个插头浪费掉,那么如果连续浪费两个插头就显然不可以,所以最好的办法就是把奇数分开,>2个奇数显然无解,因为会把插头都浪费掉。
那么奇数就放在首尾,现在我们只需要把这些东西连起来就可以了。
当然,还是尽量不放奇数,因为没什么用。
其实只要错位连接就可以了,就是a首项+1,末项-1,这样可以做到错位相连。

#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<cstdio>
#include<algorithm>
using namespace std;
 
#define LL long long
 
inline int read(){
    int x=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
const int INF=9999999;
const int MAXN=300010;
 
int N,M;
int a[MAXN+1]; 
int ans[MAXN+1],sta[MAXN+1],ge[MAXN+1];
int cnt,cnt3,cnt2;
 
int main(){
    //freopen(".in","r",stdin);
    //freopen(".out","w",stdout);
    N=read(),M=read();
    for(int i=1;i<=M;i++) {
        a[i]=read();
        if(a[i]&1) sta[++cnt]=a[i];
        else ge[++cnt2]=a[i];
    }
    if(cnt>2) {puts("Impossible"); return 0;}
    if(cnt) ans[++cnt3]=sta[cnt--];
    for(int i=1;i<=cnt2;i++) ans[++cnt3]=ge[i];
    if(cnt) ans[++cnt3]=sta[cnt--];
    for(int i=1;i<=cnt3;i++) printf("%d ",ans[i]);
    ans[1]++; ans[cnt3]--; puts("");
    if(cnt3>1){
        if(!ans[cnt3]) --cnt3;
        printf("%d
",cnt3);
        for(int i=1;i<=cnt3&&ans[i];i++) printf("%d ",ans[i]);
    }
    else {
        if(N&1){
            printf("%d
",(N+1)>>1);
            for(int i=1;i<=(N>>1);i++) printf("%d ",2);
            printf("%d
",1);
        }
        else {
            cnt3=0; int now=1;
            ans[++cnt3]=1;
            if((N>>1)&1){
                while(now<(N>>1)){
                    now+=2; ans[++cnt3]=2;
                } printf("%d
",cnt3*2);
                for(int i=1;i<=cnt3;i++){
                    printf("%d ",ans[i]);
                }
                for(int i=1;i<=cnt3;i++){
                    printf("%d ",ans[i]);
                }
            }
            else{
                while(now<(N>>1)-1){
                    now+=2; ans[++cnt3]=2;
                } printf("%d
",cnt3*2+1);
                for(int i=1;i<=cnt3;i++){
                    printf("%d ",ans[i]);
                }
                for(int i=1;i<=cnt3;i++){
                    printf("%d ",ans[i]);
                } printf("%d
",2);
            }
        }
    }
    return 0;
}

以上是关于[Agc001D] Arrays and Palindrome的主要内容,如果未能解决你的问题,请参考以下文章

AGC001 D - Arrays and Palindrome

agc045_d Lamps and Buttons

AtCoder AGC037E Reversing and Concatenating

agc001dArrays and Palindrome

[ AGC007 E ] Shik and Travel

[ AGC007 D ] Shik and Game