zoukankan      html  css  js  c++  java
  • 洛谷P2668 斗地主

    好,终于搞完了这一道毒瘤题......

    先想到搜索,然后想到状压,发现数据组数很多,又是随机,还是决定用搜索。

    先搜出的多的,于是顺序是三个顺子,然后按照多到少搜带牌,最后是不带牌。

    大体思路很简单,写起来很毒瘤...

    注意很多细节...我就是一个地方没写上界导致数组越界了。


    三带一别带自己,因为可以算在4不带里。

    王可以当对子出,当单牌带,但是不能当对牌带。

    4带2对是存在的。

    王的读入是0 1和0 2,中间有空格...

    函数调用我写的很多,复制粘贴时别写混了。

    变量++找牌的时候,要规定上界。


    大概就是这些了。

    代码6K...

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 const int N = 30;
      5 
      6 int n, ans;
      7 int bin[300000];
      8 
      9 inline void out() {
     10     for(int i = 3; i <= 15; i++) {
     11         printf("%3d", bin[i]);
     12     }
     13     printf("%3d
    ", bin[1]);
     14     return;
     15 }
     16 
     17 inline void read() {
     18     int x;
     19     scanf("%d", &x);
     20     if(x) {
     21         if(x < 3) {
     22             x += 13;
     23         }
     24         bin[x]++;
     25     }
     26     else {
     27         bin[1]++;
     28     }
     29     scanf("%d", &x);
     30     return;
     31 }
     32 void DFS(int, int, int);
     33 
     34 void one_link(int rest, int time, int t, int pos) {
     35     int l = std::max(pos, 3);
     36     while(!bin[l] && l <= 15) {
     37         l++;
     38     }
     39     if(l >= 11) {
     40         DFS(rest, time, t + 1);
     41         return;
     42     }
     43     int r = l + 1;
     44     while(r < 15 && bin[r]) {
     45         r++;
     46     }
     47 
     48     if(r - l >= 5) {
     49         for(int j = l + 5; j <= r; j++) {
     50             for(int i = l; i < j; i++) {
     51                 bin[i]--;
     52             }
     53             one_link(rest - (j - l), time + 1, t, l);
     54             for(int i = l; i < j; i++) {
     55                 bin[i]++;
     56             }
     57         }
     58     }
     59     one_link(rest, time, t, l + 1);
     60     return;
     61 }
     62 
     63 void two_link(int rest, int time, int t, int pos) {
     64     int l = std::max(pos, 3);
     65     while(bin[l] < 2 && l <= 15) {
     66         l++;
     67     }
     68     if(l >= 13) {
     69         DFS(rest, time, t + 1);
     70         return;
     71     }
     72     int r = l + 1;
     73     while(r < 15 && bin[r] > 1) {
     74         r++;
     75     }
     76 
     77     if(r - l >= 3) {
     78         for(int j = l + 3; j <= r; j++) {
     79             /// [l, j)
     80             for(int i = l; i < j; i++) {
     81                 bin[i] -= 2;
     82             }
     83             two_link(rest - 2 * (j - l), time + 1, t, l);
     84             for(int i = l; i < j; i++) {
     85                 bin[i] += 2;
     86             }
     87         }
     88     }
     89     two_link(rest, time, t, l + 1);
     90     return;
     91 }
     92 
     93 void three_link(int rest, int time, int t, int pos) {
     94     int l = std::max(pos, 3);;
     95     while(bin[l] < 3 && l <= 15) {
     96         l++;
     97     }
     98     if(l >= 14) {
     99         DFS(rest, time, t + 1);
    100         return;
    101     }
    102     int r = l + 1;
    103     while(r < 15 && bin[r] > 2) {
    104         r++;
    105     }
    106 
    107     if(r - l >= 2) {
    108         for(int j = l + 2; j <= r; j++) {
    109             /// [l, j)
    110             for(int i = l; i < j; i++) {
    111                 bin[i] -= 3;
    112             }
    113             three_link(rest - 3 * (j - l), time + 1, t, l);
    114             for(int i = l; i < j; i++) {
    115                 bin[i] += 3;
    116             }
    117         }
    118         if(r - l > 2) {
    119             three_link(rest, time, t, l + 1);
    120         }
    121         else {
    122             three_link(rest, time, t, r + 1);
    123         }
    124     }
    125     else {
    126         three_link(rest, time, t, r + 1);
    127     }
    128     return;
    129 }
    130 
    131 void four_four(int rest, int time, int t, int pos) {
    132     int p = std::max(pos, 3);
    133     while(bin[p] < 4 && p <= 15) {
    134         p++;
    135     }
    136     if(p == 16) {
    137         DFS(rest, time, t + 1);
    138         return;
    139     }
    140     bin[p] -= 4;
    141     for(int i = 3; i <= 15; i++) {
    142         if(bin[i] > 1) {
    143             bin[i] -= 2;
    144             for(int j = i; j <= 15; j++) {
    145                 if(bin[j] > 1) {
    146                     bin[j] -= 2;
    147                     four_four(rest - 8, time + 1, t, p);
    148                     bin[j] += 2;
    149                 }
    150             }
    151             bin[i] += 2;
    152         }
    153     }
    154     bin[p] += 4;
    155     four_four(rest, time, t, p + 1);
    156     return;
    157 }
    158 
    159 void four_two(int rest, int time, int t, int pos) {
    160     int p = std::max(pos, 3);
    161     while(bin[p] < 4 && p <= 15) {
    162         p++;
    163     }
    164     if(p == 16) {
    165         DFS(rest, time, t + 1);
    166         return;
    167     }
    168     bin[p] -= 4;
    169     for(int i = 1; i <= 15; i++) {
    170         if(bin[i]) {
    171             bin[i]--;
    172             for(int j = i; j <= 15; j++) {
    173                 if(bin[j]) {
    174                     bin[j]--;
    175                     four_two(rest - 6, time + 1, t, p);
    176                     bin[j]++;
    177                 }
    178             }
    179             bin[i]++;
    180         }
    181     }
    182     bin[p] += 4;
    183     four_two(rest, time, t, p + 1);
    184     return;
    185 }
    186 
    187 void three_two(int rest, int time, int t, int pos) {
    188     int p = std::max(3, pos);
    189     while(bin[p] < 3 && p <= 15) {
    190         p++;
    191     }
    192     if(p == 16) {
    193         DFS(rest, time, t + 1);
    194         return;
    195     }
    196     bin[p] -= 3;
    197     for(int i = 3; i <= 15; i++) {
    198         if(bin[i] > 1) {
    199             bin[i] -= 2;
    200             three_two(rest - 5, time + 1, t, p);
    201             bin[i] += 2;
    202         }
    203     }
    204     bin[p] += 3;
    205     three_two(rest, time, t, p + 1);
    206     return;
    207 }
    208 
    209 void three_one(int rest, int time, int t, int pos) {
    210     int p = std::max(pos, 3);
    211     while(bin[p] < 3 && p <= 15) {
    212         p++;
    213     }
    214     if(p == 16) {
    215         DFS(rest, time, t + 1);
    216         return;
    217     }
    218     bin[p] -= 3;
    219     for(int i = 1; i <= 15; i++) {
    220         if(bin[i] && i != p) {
    221             bin[i]--;
    222             three_one(rest - 4, time + 1, t, p);
    223             bin[i]++;
    224         }
    225     }
    226     bin[p] += 3;
    227     three_one(rest, time, t, p + 1);
    228     return;
    229 }
    230 
    231 void DFS(int rest, int time, int t) {
    232     if(!rest) {
    233         ans = std::min(ans, time);
    234         return;
    235     }
    236     if(time >= ans - 1) {
    237         return;
    238     }
    239     if(!t) {
    240         one_link(rest, time, t, 0);
    241     }
    242     else if(t == 1) {
    243         two_link(rest, time, t, 0);
    244     }
    245     else if(t == 2) {
    246         three_link(rest, time, t, 0);
    247     }
    248     else if(t == 3) {
    249         four_four(rest, time, t, 0);
    250     }
    251     else if(t == 4) {
    252         four_two(rest, time, t, 0);
    253     }
    254     else if(t == 5) {
    255         three_two(rest, time, t, 0);
    256     }
    257     else if(t == 6) {
    258         three_one(rest, time, t, 0);
    259     }
    260     else {
    261         int a = 0;
    262         for(int i = 1; i <= 15; i++) {
    263             a += (bin[i] > 0);
    264         }
    265         ans = std::min(ans, time + a);
    266     }
    267     return;
    268 }
    269 
    270 inline void solve() {
    271     ans = 0;
    272     for(int i = 1; i <= 15; i++) {
    273         ans += (bin[i] > 0);
    274     }
    275     DFS(n, 0, 0);
    276     printf("%d
    ", ans);
    277     return;
    278 }
    279 
    280 int main() {
    281     int T;
    282     scanf("%d%d", &T, &n);
    283     while(T--) {
    284         for(int i = 1; i <= n; i++) {
    285             read();
    286         }
    287         solve();
    288         if(T) {
    289             memset(bin, 0, sizeof(bin));
    290         }
    291     }
    292 
    293     return 0;
    294 }
    AC代码

    顺手把增强版也A了,跑的贼快。

    数组300000是之前调的,忘了改回来。

  • 相关阅读:
    php高级进阶系列文章--第二篇(PHP基础知识复习)
    开发常用linux命令
    composer 包管理工具学习总结
    微信菜单加emoji图标
    onethink导出excel
    onethinkp导入excel
    导航效果css
    php发送邮件
    js初学者的div移动
    html图片预览
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/9619942.html
Copyright © 2011-2022 走看看