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

Posted Sakits

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 906B. Seating of Students(构造+DFS)相关的知识,希望对你有一定的参考价值。

  行和列>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)的主要内容,如果未能解决你的问题,请参考以下文章

codeforces 906C

CodeForces906 D. Power Tower 扩展欧拉定理

CodeForces 906D Power Tower <<欧拉降幂

Codeforces Round #454 (Div. 2, based on Technocup 2018 Elimination Round 4) D. Seating of Students [

Codeforces 906 D Power Tower

CF906DPower Tower