codeforce 906 SOL (B)

题目大意:老师要排座位,要求每个人的四周的邻居不是原来的,求方案

题目链接

SOL :min(n,m)<4 就暴搜,否则就构造。

#include<bits/stdc++.h>  
using namespace std;  
#define N 500017
int n,m,p[N],dx[4] = {0,1,0,-1},dy[4]={1,0,-1,0};  
bool check(int i, int j){   
    int x=(i-1)/m+1,y=(i-1)%m+1,x2=(j-1)/m+1,y2=(j-1)%m+1;  
    for (int k=0;k<4;k++) if (x+dx[k]==x2&&y+dy[k]==y2)  return 1;  
    return 0;  
}  
void write(int x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);}
inline void writel(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); }
bool dfs(int i) {  
    if (i>=n*m+1) return 1;  
    int x=(i-1)/m+1,y=(i-1)%m+1;  
    for (int j=i;j<=n*m;j++)  {   
      swap(p[i],p[j]);  
      if (x^1&&check(p[i],p[(x-2)*m+y])) continue;  
      if (y^1&&check(p[i],p[(x-1)*m+y-1])) continue;  
      if (dfs(i+1))return 1;  swap(p[i], p[j]);  
    }  
    return 0;  
} 
int main(){  
    freopen("b.in","r",stdin);
    scanf("%d%d", &n, &m);  
    for (int i=1;i<=n;i++)  
        for (int j=1;j<=m;j++)  
            p[(i-1)*m+j]=(i-1)*m+j;  
    if (!dfs(1))  return puts("NO"), 0;  
    puts("YES");  
    for (int i=1;i<=n;i++,putchar('\n'))  
        for (int j=1;j<=m;j++)  
          writel(p[(i-1)*m+j]);
    return 0;
}  

 

posted @ 2018-01-16 19:13  泪寒之雪  阅读(154)  评论(0编辑  收藏  举报