• AGC001 D


    把回文串的相等关系连一下,发现最后要求的是一笔画问题
    注意到奇数长度的中间有一个单独没有连线的,所以a数组至多有两个奇数值
    如果没有奇数,那么b在最前面放一个1,然后把a[1]~a[m-1]放上去,这样就是错位着一笔画了,然后剩下一个奇数值连成若干2中间一个1的样子;
    如果一个奇数,那么把奇数放到最后,然后前面像上面一样错位相连,最后剩一个偶数,全连2即可
    如果两个奇数,那么把奇数放到两端,然后b[1]=a[1]+1,这样就相当于一个奇数,错位相连再填2即可

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int N=100005;
    int n,m,a[N],b[N],tot,w[N],top;
    int read()
    {
    	int r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    int main()
    {
    	n=read(),m=read();
    	for(int i=1;i<=m;i++)
    	{
    		a[i]=read();
    		if(a[i]&1)
    			w[++top]=i;
    	}
    	if(top>2)
    	{
    		puts("Impossible");
    		return 0;
    	}
    	if(top==0)
    	{
    		b[++tot]=1;
    		for(int i=1;i<m;i++)
    			b[++tot]=a[i];
    		for(int i=1;i<=(a[m]-1)/2/2;i++)
    			b[++tot]=2;
    		b[++tot]=1;
    		for(int i=(a[m]-1)/2/2+1;i<=(a[m]-1)/2;i++)
    			b[++tot]=2;
    	}
    	if(top==1)
    	{
    		swap(a[w[1]],a[m]);
    		b[++tot]=1;
    		for(int i=1;i<m;i++)
    			b[++tot]=a[i];
    		for(int i=1;i<=(a[m]-1)/2;i++)
    			b[++tot]=2;
    	}
    	if(top==2)
    	{
    		swap(a[w[1]],a[m]);
    		swap(a[w[2]],a[1]);
    		b[++tot]=a[1]+1;
    		for(int i=2;i<m;i++)
    			b[++tot]=a[i];
    		for(int i=1;i<=(a[m]-1)/2;i++)
    			b[++tot]=2;
    	}
    	for(int i=1;i<=m;i++)
    		printf("%d ",a[i]);
    	printf("
    %d
    ",tot);
    	for(int i=1;i<=tot;i++)
    		printf("%d ",b[i]);
    	return 0;
    }
    
  • 相关阅读:
    bzoj 3670: [Noi2014]动物园
    bzoj 2878: [Noi2012]迷失游乐园
    51nod 1348 乘积之和
    51nod 1514 美妙的序列
    AtCoder Grand Contest 002 D
    bzoj 3451 Normal
    LOJ #6119. 「2017 山东二轮集训 Day7」国王
    51nod 1752 哈希统计
    计蒜客 百度地图的实时路况
    Codeforces 549F Yura and Developers
  • 原文地址:https://www.cnblogs.com/lokiii/p/10920753.html
Copyright © 2020-2023  润新知