• POJ2965 The Pilots Brothers' refrigerator(枚举)


    题目链接

    题意:

    给出一个4*4矩阵,每个单元要么是 '+', 要么是 '-',每次可以选一个单元,翻转它以及它所在的行和列。求使全部为'-'的最少操作数,并求出操作步骤。

    分析:

    这题和 1753 类似,但此题的后台数据显然要多余后者。

    可以利用打表,算出所有的翻转状态。存入sw。打表代码如下:

    int swc(int i) {
        int nsw = 0, j;
        nsw |= (1<<i);
    
        j = i;
        while(j % 4 != 0) {
            nsw |= (1<<j);
            j--;
        }
        nsw |= (1<<j);
    
        j = i;
        while((j+1) % 4 != 0) {
            nsw |= (1<<j);
            j++;
        }
        nsw |= (1<<j);
    
        j = i;
        while(j >= 0) {
            nsw |= (1<<j);
            j -= 4;
        }
    
        j = i;
        while(j < 16) {
            nsw |= (1<<j);
            j += 4;
        }
    
        return nsw;
    }
    View Code

    即int sw[16] = {4383, 8751, 17487, 34959, 4593, 8946, 17652, 35064, 7953, 12066,20292, 36744, 61713, 61986, 62532, 63624};

    接着直接枚举。 不过要注意的是,如果先入队列,取出时标记,是会TLE的。所以对于新状态要先标记,再放入队列。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <queue>
    
    using namespace std;
    
    const int maxn = (1<<16);
    int p[maxn], x[maxn], y[maxn], step[maxn], n;
    bool vis[maxn];
    
    int sw[16] = {4383, 8751, 17487, 34959, 4593, 8946, 17652, 35064, 7953, 12066,
        20292, 36744, 61713, 61986, 62532, 63624};
    
    int BFS(int n) {
        memset(p, 0, sizeof(p));
        memset(vis, false, sizeof(vis));
        queue<int> Q;
    
        Q.push(n);
        step[n] = 0;
        vis[n] = true;
    
        while(!Q.empty()) {
            int e = Q.front(); Q.pop();
    
            if(e == 0) return step[e];
    
            for(int i=0; i<16; i++) {
                int state = e ^ sw[i];
                if(!vis[state]) {
                    Q.push(state);
                    vis[state] = true;
                    p[state] = e;
                    x[state] = 4-(i / 4);
                    y[state] = 4-(i % 4);
                    step[state] = step[e] +1;
                }
            }
        }
    
        return 0;
    }
    
    void print(int s) {
        if(s != n) {
            print(p[s]);
            printf("%d %d\n", x[s], y[s]);
        }
    }
    
    int main() {
        n = 0;
        char s[10];
    
        for(int i=0; i<4; i++) {
            cin >> s;
            for(int j=0; j<4; j++) {
                n <<= 1;
                if(s[j] == '+') n |= 1;
            }
        }
    
        printf("%d\n", BFS(n));
    
        print(0);
    
    
        return 0;
    }
  • 相关阅读:
    金额与数字转化常用实用几个JS方法
    Jdb命令 The Java Debugger
    GLOBAL TEMPORARY TABLE
    安装与配置Nginx
    MySQL二进制安装与密码破解
    基于FPM构建企业RPM包
    安装Tomcat
    nginx配置优化
    DHCP原理及配置(三个小实验)
    DNS主、从服务器的配置
  • 原文地址:https://www.cnblogs.com/tanhehe/p/3138950.html
Copyright © 2020-2023  润新知