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

Codeforces 906B. Seating of Students(构造+DFS)

时间:2017-12-24 22:45:18      阅读:396      评论:0      收藏:0      [点我收藏+]

标签:class   display   splay   dfs   stream   判断   get   color   def   

  行和列>4的可以直接构造,只要交叉着放就好了,比如1 3 5 2 4和2 4 1 3 5,每一行和下一行用不同的方法就能保证没有邻居。

  其他的可以用爆搜,每次暴力和后面的一个编号交换并判断可行性。

  写dfs的话其实行和列>4的就不用刻意构造了,这个dfs方法可以$O(n*m)$跑出一个构造方案。

技术分享图片
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#define ll long long
using namespace std;
const int maxn=500010;
int n, m;
int pos[maxn];
int dx[4]={0, 1, 0, -1}, dy[4]={1, 0, -1, 0};
inline void read(int &k)
{
    int f=1; k=0; char c=getchar();
    while(c<0 || c>9) c==- && (f=-1), c=getchar();
    while(c<=9 && c>=0) k=k*10+c-0, c=getchar();
    k*=f;
}
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;
}
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(pos[i], pos[j]);
        if(x!=1 && check(pos[i], pos[(x-2)*m+y])) continue;
        if(y!=1 && check(pos[i], pos[(x-1)*m+y-1])) continue;
        if(dfs(i+1)) return 1;
        swap(pos[i], pos[j]);
    }
    return 0;
}
int main()
{
    read(n); read(m);
    for(int i=1;i<=n;i++) 
    for(int j=1;j<=m;j++) 
    pos[(i-1)*m+j]=(i-1)*m+j;
    if(!dfs(1)) return puts("NO"), 0;
    puts("YES");
    for(int i=1;i<=n;i++, puts("")) 
    for(int j=1;j<=m;j++) 
    printf("%d ", pos[(i-1)*m+j]);
} 
View Code

 

Codeforces 906B. Seating of Students(构造+DFS)

标签:class   display   splay   dfs   stream   判断   get   color   def   

原文地址:http://www.cnblogs.com/Sakits/p/8099234.html

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