Codeforces Round #454 Div. 2 D. Seating of Students

D. Seating of Students

题意: 给出 n 、m,  表示原来有 n*m 的矩阵形的人,每个人的标号是从1 到 n*m。  要你重新排列,使得原来相邻的人变得不相邻,输出排列后的标号。

相邻的定义:上下挨着,或者左右挨着。

tags: 蛇皮题。。好费时间,还不如去做E题。。

瞎搞做的,,分三种情况,

1】n<5,m<5时,直接暴搜。直观上看复杂度是16^16,但其实大部分的情况会在中途舍弃掉,并不会慢。

2】m>=5 时,奇数列放前面,偶数列放后面,再把偶数行偏移一下就 OK。

比如 2*5, 就是1 3 5 2 4
       7 9 6 8 10

3】m<5,但 n>=5 时, 也是和 2】一样,只不过麻烦点。

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 200005;

int a[100][100], n, m, ans[100][100];
bool vis[N];
bool XL(int x, int y)
{
    if(x > y) swap(x, y);
    return  (y-x==m) || ((x%m!=0) && (x+1==y));
}
bool dfs(int r, int c, int u)
{
    a[r][c] = u;   vis[u] = true;
    if(r==n && c==m) {
        ans[r][c] = u;
        return true;
    }
    int tr = r,  tc = c+1;
    if(tc > m) tr=r+1, tc=1;
    rep(i, 1, n*m)
        if(!vis[i])
        {
            if(tc!=1 && XL(u, i)) continue;
            if(tr>1 && XL(a[tr-1][tc], i)) continue;
            if( dfs(tr, tc, i) )
            {
                ans[r][c] = u;
                return true;
            }
        }
    a[r][c] = 0;   vis[u] = false;
    return false;
}
int num[N][6], num2[N][6];
int main()
{
    scanf("%d%d", &n, &m);
    if(n<5 && m<5)
    {
        bool flag = false;
        rep(i,1,n*m)
            if( dfs(1, 1, i) )
            {
                puts("YES");
                rep(ci,1,n)
                    rep(cj,1,m)
                        printf("%d%c", a[ci][cj], " 
"[cj==m]);
                flag = true;
                break;
            }
        if(!flag) puts("NO");
    }
    else if(m >= 5)
    {
        puts("YES");
        int ans1, tmp, tmp2;
        rep(i,1,n) rep(j,1,m)
        {
            tmp = (m+1)/2,  tmp2 = (i-1)*m;
            if(i&1)
            {
                if(j==1) ans1 = (m&1) ? (i*m-1) : (i*m);
                else
                {
                    if(j <= tmp+1) ans1 = tmp2+2*(j-1)-1;
                    else ans1 = tmp2+(j-tmp-1)*2;
                }
            }
            else
            {
                if(j <= tmp) ans1 = tmp2+2*j-1;
                else ans1 = tmp2+(j-tmp)*2;
            }
            printf("%d%c", ans1, " 
"[j==m]);
        }
    }
    else
    {
        puts("YES");
        int ans1, tmp, tmp2;
        rep(i,1,n) rep(j,1,m)
            num[i][j] = m*(i-1)+j;
        rep(j,1,m) rep(i,1,n)
        {
            tmp = (n+1)/2, tmp2 = (j-1)*n;
            if(j&1)
            {
                if(i==1) ans1 = num[(n&1) ? (n-1) : n][j];
                else
                {
                    if(i <= tmp+1) ans1 = num[2*(i-1)-1][j];
                    else ans1 = num[(i-tmp-1)*2][j];
                }
            }
            else
            {
                if(i <= tmp) ans1 = num[2*i-1][j];
                else ans1 = num[(i-tmp)*2][j];
            }
            num2[i][j] = ans1;
        }
        rep(i,1,n) rep(j,1,m)
            printf("%d%c", num2[i][j], " 
"[j==m]);
    }

    return 0;
}
原文地址:https://www.cnblogs.com/sbfhy/p/8127041.html