zoukankan      html  css  js  c++  java
  • uva 10318 Security Panel (dfs+剪枝)

    uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1259

      压缩Panel的全部状态,预处理出每个位置的变化,然后dfs搜索全部情况。不过这样是会超时的,所以我在搜索的过程中加上剪枝,预判出之前的状态是否能够使得最后整个Panel充满,如果不能就尽早跳出搜索。加上小小的一个剪枝,速度提升估计了不下1000倍,由原来的超时,最后只要0.008s就完成了!

    代码如下:

    View Code
     1 #define REP(i, n) for (int i = 0; i < (n); i++)
     2 #define REP_1(i, n) for (int i = 1; i <= (n); i++)
     3 
     4 const int dir[9][2] = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 0}, {0, 1}, {1, -1}, {1, 0}, {1, 1}};
     5 char buf[3][4];
     6 LL pat[25], ok[6];
     7 
     8 void pntPat(LL n) {
     9     printf("~~~~~ %lld ~~~~~~\n", n);
    10     DEC(i, 63, 0) {
    11         if (n & (1ll << i)) putchar('1');
    12         else putchar('0');
    13         if ((i & 7) == 0) puts("");
    14     }
    15 }
    16 
    17 void makePat(int n, int m) {
    18     int t = (1 << m) - 1 << 1;
    19     REP(i, n + 1) {
    20         ok[i] = 0;
    21         REP(j, i) {
    22             ok[i] |= t;
    23             ok[i] <<= 8;
    24         }
    25 //        pntPat(ok[i]);
    26     }
    27     REP(i, n) {
    28         REP(j, m) {
    29             int id = i * m + j;
    30             pat[id] = 0;
    31             REP(k, 9) {
    32                 int x = dir[k][0] + i + 1, y = dir[k][1] + j + 1;
    33                 if (buf[k / 3][k % 3] == '*') pat[id] |= 1ll << x * 8 + y;
    34             }
    35 //            cout << id << endl;
    36 //            pntPat(pat[id]);
    37         }
    38     }
    39 }
    40 
    41 int rec[30], cnt;
    42 
    43 bool dfs(LL cur, int pos, int end, int n, int m) {
    44     if ((cur & ok[n]) == ok[n]) return true;
    45     if (pos >= end) return false;
    46     int t = pos / m - 1;
    47 //    cout << pos << ends << m << ends << t << endl;
    48     if (t > 0 && (cur & ok[t]) != ok[t]) return false;
    49     if (dfs(cur, pos + 1, end, n, m)) return true;
    50     rec[cnt++] = pos + 1;
    51     if (dfs(cur ^ pat[pos], pos + 1, end, n, m)) return true;
    52     cnt--;
    53     return false;
    54 }
    55 
    56 void work(int n, int m) {
    57     makePat(n, m);
    58     cnt = 0;
    59     if (dfs(0, 0, n * m, n, m)) {
    60         REP(i, cnt) {
    61             if (i) putchar(' ');
    62             printf("%d", rec[i]);
    63         }
    64         puts("");
    65     } else {
    66         puts("Impossible.");
    67     }
    68 }
    69 
    70 int main() {
    71 //    freopen("in", "r", stdin);
    72     int n, m, cas = 1;
    73     while (~scanf("%d%d", &n, &m) && (n || m)) {
    74         REP(i, 3) scanf("%s", buf[i]);
    75         printf("Case #%d\n", cas++);
    76         work(n, m);
    77     }
    78     return 0;
    79 }

    ——written by Lyon

  • 相关阅读:
    Django Rest Framework(版本、解析器、序列化、数据验证)
    Django Rest Framework(认证、权限、限制访问频率)
    Django rest_framework 认证源码流程
    RESTful API
    微信网页第三方登录原理
    web实现QQ第三方登录 开放平台-web实现QQ第三方登录
    H5版如何在微信外(非微信浏览器)进行微信支付技术方案
    支付宝手机网站接入2-支付结果异步通知
    支付宝手机网站接入1
    Npoi导入导出Excel操作
  • 原文地址:https://www.cnblogs.com/LyonLys/p/uva_10318_Lyon.html
Copyright © 2011-2022 走看看