码迷,mamicode.com
首页 > 其他好文 > 详细

[Agc001D] Arrays and Palindrome

时间:2018-09-02 11:03:10      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:stdout   cstring   har   math   arrays   分享图片   max   数组   题目   

[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\n",cnt3);
        for(int i=1;i<=cnt3&&ans[i];i++) printf("%d ",ans[i]);
    }
    else {
        if(N&1){
            printf("%d\n",(N+1)>>1);
            for(int i=1;i<=(N>>1);i++) printf("%d ",2);
            printf("%d\n",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\n",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\n",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\n",2);
            }
        }
    }
    return 0;
}

[Agc001D] Arrays and Palindrome

标签:stdout   cstring   har   math   arrays   分享图片   max   数组   题目   

原文地址:https://www.cnblogs.com/wxjor/p/9572882.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!