zoukankan      html  css  js  c++  java
  • poj 2741 Colored Cubes(dfs暴力枚举)

    2741 -- Colored Cubes

      十分好的一个暴力枚举题,题意是,给出最多4个筛子,每个面都有一个颜色标记,要求求出最少改变多少个面,使得这些筛子可以通过某些旋转使其完全相同。

      刚接到这题的时候,有点老鼠拉龟的感觉,首先想到的居然是dp。。。然后细心一想,这个题最多才4个筛子,何不直接暴力枚举呢?枚举复杂度最多才到O(24^n),因为筛子一共有24种放置的方法。然后一个问题就来了,这24种状态要怎么搞出来?一个不小心错了一个数字就很难debug 的了。于是,我在草稿纸上写了前面是1的4种情况,然后发现其余的,前面是2~6的各自的4种情况都是一样的转换方式,所以之后的直接利用转换即刻得到,具体查看代码。

      最后套上一个dfs就大功告成了!

    View Code
     1 const int base[6][6] = { {0, 1, 2, 3, 4, 5}, {1, 0, 3, 2, 5, 4},
     2                    {2, 0, 1, 4, 5, 3}, {3, 0, 4, 1, 5, 2},
     3                    {4, 0, 2, 3, 5, 1}, {5, 1, 3, 2, 4, 0}};
     4 const int convert[4][6] = { {0, 1, 2, 3, 4, 5}, {0, 2, 4, 1, 3, 5},
     5                       {0, 4, 3, 2, 1, 5}, {0, 3, 1, 4, 2, 5}};
     6 
     7 void getDice(int n, int *dice) {
     8     int x = n >> 2, y = n & 3;
     9     REP(i, 6) dice[i] = base[x][convert[y][i]];
    10 }
    11 
    12 int st[4][6], mini, curID, dice[4][6];
    13 map<string, int> id;
    14 
    15 int getID(char *s) {
    16     return id.find(s) == id.end() ? id[s] = curID++ : id[s];
    17 }
    18 
    19 void input(int n) {
    20     char buf[25];
    21     curID = 0;
    22     id.clear();
    23     REP(i, n) REP(j, 6) {
    24         scanf("%s", buf);
    25         dice[i][j] = getID(buf);
    26     }
    27 }
    28 
    29 int stat[24];
    30 
    31 int cal(int n) {
    32     int ret = 0;
    33     REP(i, 6) {
    34         int mx = 0;
    35         _clr(stat);
    36         REP(j, n) {
    37             stat[dice[j][st[j][i]]]++;
    38             mx = max(mx, stat[dice[j][st[j][i]]]);
    39         }
    40         ret += n - mx;
    41         if (ret >= mini) return inf;
    42     }
    43     return ret;
    44 }
    45 
    46 void dfs(int n, int p) {
    47     if (p >= n) {
    48         mini = min(mini, cal(n));
    49         return ;
    50     }
    51     REP(i, 24) {
    52         getDice(i, st[p]);
    53         dfs(n, p + 1);
    54     }
    55 }
    56 
    57 int work(int n) {
    58     mini = inf;
    59     getDice(0, st[0]);
    60     dfs(n, 1);
    61     return mini;
    62 }
    63 
    64 int main() {
    65 //    freopen("in", "r", stdin);
    66     int n;
    67     while (~scanf("%d", &n) && n) {
    68         input(n);
    69         printf("%d\n", work(n));
    70     }
    71     return 0;
    72 }

    ——written by Lyon

  • 相关阅读:
    基于PI的Webservice发布实例
    SM30 表格维护生成器
    各种财务凭证的冲销
    SAP后台作业记录操作
    特性,批次特性建立的BAPI函數
    Windows 上 Nginx 路径的陷阱
    BitKeeper 和 Git
    Javascript 正则验证带 + 号的邮箱地址
    FastAdmin 开发第三天:认识目录
    PHP 中的对象传递
  • 原文地址:https://www.cnblogs.com/LyonLys/p/poj_2741_Lyon.html
Copyright © 2011-2022 走看看