zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    distcc加速内核编译
    ssh不检查server变化
    bbb u-boot SPI 启动
    Debian NAT共享上网
    Debian Epson L455 打印机
    Learn CMake's Scripting Language in 15 Minutes (ZZ)
    网络启动并安装Debian
    GNU LD 脚本学习笔记
    JLink defective
    获取真实mac地址
  • 原文地址:https://www.cnblogs.com/Sakits/p/8099234.html
Copyright © 2011-2022 走看看