C. Palindromic Matrix

 http://codeforces.com/contest/1118/problem/C

题意:给n(0-20),和n*n数组,构造n*n回文数组,行和列调换不变

思路:n为偶时,必然每个数时4的倍数;奇时个数为奇数的一个是最中间,中间行和列两两构造,剩下的四个四个构造;

#include<algorithm>
#include<set>
#include<vector>
#include<queue>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<set>
#include<vector>
#include<queue>
#include<cmath>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<ctime>
#include<map>
#include<stack>
#include<string>
using namespace std;

#define sfi(i) scanf("%d",&i)
#define pri(i) printf("%d\n",i)
#define sff(i) scanf("%lf",&i)
#define ll long long
#define mem(x,y) memset(x,y,sizeof(x))
#define INF 0x3f3f3f3f
#define eps 1e-6
#define PI acos(-1)
#define lowbit(x) ((x)&(-x))
#define zero(x) (((x)>0?(x):-(x))<eps)
#define fl() printf("flag\n")
ll gcd(ll a,ll b){while(b^=a^=b^=a%=b);return a;}
const int maxn=1e4+9;
const int mod=1e9+7;

template <class T>
inline void sc(T &ret)
{
    char c;
    ret = 0;
    while ((c = getchar()) < '0' || c > '9');
    while (c >= '0' && c <= '9')
    {
        ret = ret * 10 + (c - '0'), c = getchar();
    }
}

int num[maxn+10];
int a[100][100];
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n*n;i++)
    {
        int x;
        cin>>x;
        num[x]++;
    }
    if(n%2==0)
    {
        for(int i=1;i<=maxn;i++)
        {
            if(num[i]%4)
            {
                cout<<"NO"<<endl;
                return 0;
            }
        }
        int id=1;
        for(int i=0;i<n/2;i++)
        {
            for(int j=0;j<n/2;j++)
            {
                while(1)
                {
                    if(num[id])
                    {
                        a[i][j] = id;
                        a[n-i-1][j] = id;
                        a[i][n-j-1] = id;
                        a[n-i-1][n-j-1] = id;
                        num[id] -= 4;
                        break;
                    }
                    id++;
                    if(id>1000)
                    {
                        cout<<"NO"<<endl;
                        return 0;
                    }

                }

            }
        }
        cout<<"YES"<<endl;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                cout<<a[i][j]<<" ";
            }
            cout<<endl;
        }
    }
    else
    {
        int ji=0;
        for(int i=1;i<=maxn;i++)
        {
            if(num[i]%2)
            {
                ji++;
            }
        }
        if(ji!=1)
        {
            cout<<"NO"<<endl;
            return 0;
        }
        //处理最中间的
        for(int i=1;i<=maxn;i++)
        {
            if(num[i]%2)
            {
                a[n/2][n/2]=i;
                num[i]--;
                break;
            }
        }

        //处理中间行,列

        //先用2个的
        int cnt=0;
        for(int i=1;i<=maxn;i++)
        {
            if(cnt==n-1) break;
            if(num[i]%4)
            {
                    if(cnt<n/2)
                     {
                        //cout<<n/2<<" "<<cnt<<" "<<i<<endl<<endl;;
                         a[n/2][cnt]=i;
                         a[n/2][n-cnt-1]=i;
                         num[i]-=2;
                     }
                     else
                     {
                         //cout<<cnt-n/2<<" "<<n/2<<" "<<i<<endl<<endl;
                         a[(cnt-n/2)][n/2]=i;
                         a[n-(cnt-n/2)-1][n/2]=i;
                         num[i]-=2;
                     }
                     cnt++;
            }
        }

        //2个不够用4个的
        for(int i=1;i<=maxn;i++)
        {
            if(cnt==n-1) break;
            if(num[i])
            {
                while(num[i])
                {
                    if(cnt==n-1) break;
                    if(cnt<n/2)
                     {
                        //cout<<n/2<<" "<<cnt<<" "<<i<<endl<<endl;;
                         a[n/2][cnt]=i;
                         a[n/2][n-cnt-1]=i;
                         num[i]-=2;
                     }
                     else
                     {
                         //cout<<cnt-n/2<<" "<<n/2<<" "<<i<<endl<<endl;
                         a[(cnt-n/2)][n/2]=i;
                         a[n-(cnt-n/2)-1][n/2]=i;
                         num[i]-=2;
                     }
                     cnt++;
                }

            }
        }
        /*for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                cout<<a[i][j]<<" ";
            }
            cout<<endl;
        }*/
        int id=1;
        for(int i=0;i<n/2;i++)
        {
            for(int j=0;j<n/2;j++)
            {
                while(1)
                {
                    if(num[id]%4==0&&num[id])
                    {
                        a[i][j] = id;
                        a[n-i-1][j] = id;
                        a[i][n-j-1] = id;
                        a[n-i-1][n-j-1] = id;
                        num[id] -= 4;
                        break;
                    }
                    id++;
                    if(id>1000)
                    {
                        cout<<"NO"<<endl;
                        return 0;
                    }

                }

            }
        }
        cout<<"YES"<<endl;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                cout<<a[i][j]<<" ";
            }
            cout<<endl;
        }
    }
    return 0;
}

python:

纯粹学习,运行时间很长,学会了构造二维数组 

maxn=10009

num=[0]*maxn
a=[([0 for i in range(maxn)])for i in range(maxn)]

n=int(input())
mid=int(n/2)

op=input()
op=op.split()
for i in range(len(op)):
    op[i]=int(op[i])
    num[op[i]]+=1

if n%2==0 :
    for i in range(1,maxn):
        if num[i]%4:
            print("NO")
            exit()
    id=1
    for i in range(mid):
        for j in range(mid):
            while 1:
                if num[id]:
                    a[i][j]=id
                    a[n-i-1][j]=id
                    a[i][n - j - 1] = id
                    a[n - i - 1][n - j - 1] = id
                    num[id] -= 4
                    break
                id+=1
                if id>1000:
                    print("NO")
                    exit()

    print('YES')
    for i in range(n):
        for j in range(n):
            print(a[i][j],end=' ')
        print()

else:
    ji=0
    for i in range(1,maxn):
        if num[i]%2:
            ji+=1
    if ji!=1:
        print('NO')
        exit()

    for i in range(1,maxn):
        if num[i]%2:
            a[mid][mid]=i
            num[i]-=1
            break

    cnt=0
    for i in range(1,maxn):
        if cnt==n-1:
            break
        if num[i]%4:
            if cnt<mid:
                a[mid][cnt]=i
                a[mid][n-cnt-1]=i
                num[i]-=2
            else:
                a[cnt-mid][mid]=i
                a[n-(cnt-mid)-1][mid]=i
                num[i]-=2
            cnt+=1
    for i in range(1,maxn):
        if cnt==n-1:
            break
        if num[i]:
            while num[i]:
                if cnt==n-1:break
                if cnt<mid:
                    a[mid][cnt]=i
                    a[mid][n-cnt-1]=i
                    num[i]-=2
                else:
                    a[cnt-mid][mid]=i
                    a[n-(cnt-mid)-1][mid]=i
                    num[i]-=2
                cnt+=1

    id=1
    for i in range(0,mid):
        for j in range(0,mid):
            while 1:
                if(num[id]%4==0 and num[id]):
                    a[i][j] = id
                    a[n - i - 1][j] = id
                    a[i][n - j - 1] = id
                    a[n - i - 1][n - j - 1] = id
                    num[id] -= 4
                    break

                id+=1
                if id>1000:
                    print('NO')
                    exit()

    print('YES')
    for i in range(0,n):
        for j in range(0,n):
            print(a[i][j],end=' ')
        print()

猜你喜欢

转载自blog.csdn.net/weixin_39132605/article/details/87869756