zoukankan      html  css  js  c++  java
  • 【POJ】1084 Square Destroyer

    1. 题目描述
    由$n imes n, n in [1, 5]$的正方形由$2 imes n imes (n+1)$根木棍组成,可能已经有些木棍被破坏,求至少还需破坏多少木根,可以使得不存在任何正方形?

    2. 基本思路
    这是一道非常有趣的题目,可以使用IDA*解也可以用DLX解。可以试试5 0这组数据比较两者的性能差异。
    (1) IDA*
    使用IDA*处理,是因为最后的解的范围一定不是很大,因为数据很小。至多也就60根木棍。
    首先可以预处理分别对正方形和木棍进行编号,进而预处理破坏每根木棍可以影响的正方形。
    由于木棍和正方形都不超过60个,因此可以采用longlong进行状态压缩,一定要装压,否则就哭吧。
    每次选择当前仍然存在的最小正方形,然后枚举它的每条边进行深搜。

    (2) DLX
    使用DLX解这道题很容易理解, 而且解5 0这组数据也很快。
    首先仍然可以使用上述的预处理方法。从而可以得到当前木棍中仍然存在的正方形。
    如果,当前不存在正方形则直接输出0。否则以正方形的个数初始化DLX。
    接下来,枚举每条边,搜索它可以影响到的正方形,建立一个可行方案。
    直接套用DLX可解,注意DLX加入H函数可以加速,而且效果还是挺明显的。

    3. 代码
    (1)IDA*

      1 /* 1084 */
      2 #include <iostream>
      3 #include <sstream>
      4 #include <string>
      5 #include <map>
      6 #include <queue>
      7 #include <set>
      8 #include <stack>
      9 #include <vector>
     10 #include <deque>
     11 #include <bitset>
     12 #include <algorithm>
     13 #include <cstdio>
     14 #include <cmath>
     15 #include <ctime>
     16 #include <cstring>
     17 #include <climits>
     18 #include <cctype>
     19 #include <cassert>
     20 #include <functional>
     21 #include <iterator>
     22 #include <iomanip>
     23 using namespace std;
     24 //#pragma comment(linker,"/STACK:102400000,1024000")
     25 
     26 #define sti                set<int>
     27 #define stpii            set<pair<int, int> >
     28 #define mpii            map<int,int>
     29 #define vi                vector<int>
     30 #define pii                pair<int,int>
     31 #define vpii            vector<pair<int,int> >
     32 #define rep(i, a, n)     for (int i=a;i<n;++i)
     33 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
     34 #define clr                clear
     35 #define pb                 push_back
     36 #define mp                 make_pair
     37 #define fir                first
     38 #define sec                second
     39 #define all(x)             (x).begin(),(x).end()
     40 #define SZ(x)             ((int)(x).size())
     41 #define lson            l, mid, rt<<1
     42 #define rson            mid+1, r, rt<<1|1
     43 #define INF                0x3f3f3f3f
     44 #define mset(a, val)    memset(a, (val), sizeof(a))
     45 
     46 #define LL long long
     47 
     48 typedef struct {
     49     vector<LL> sq;
     50     int sz;
     51 } sqInfo_t;
     52 
     53 
     54 const int maxm = 65;
     55 int rowId[6][6];
     56 int colId[6][6];
     57 int n, tot;
     58 LL st;
     59 sqInfo_t sqInfo[6];
     60 
     61 void init_sq(int n) {
     62     int cnt = 0;
     63     sqInfo_t& info = sqInfo[n];
     64     vector<LL>& sq = info.sq;
     65     int& sz = info.sz;
     66     
     67     rep(i, 0, n) {
     68         rep(j, 0, n)
     69             rowId[i][j] = cnt++;
     70         rep(j, 0, n+1)
     71             colId[i][j] = cnt++;
     72     }
     73     rep(j, 0, n)
     74         rowId[n][j] = cnt++;
     75 
     76     cnt = 0;
     77     rep(i, 0, n) {
     78         rep(j, 0, n) {
     79             rep(k, 1, n+1) {
     80                 if (i+k>n || j+k>n)
     81                     break;
     82 
     83                 LL val = 0;
     84 
     85                 // Top
     86                 rep(l, 0, k) {
     87                     val |= (1LL << rowId[i][j+l]);
     88                 }
     89 
     90                 // Left
     91                 rep(l, 0, k) {
     92                     val |= (1LL << colId[i+l][j]);
     93                 }
     94 
     95                 // Down
     96                 rep(l, 0, k) {
     97                     val |= (1LL << rowId[i+k][j+l]);
     98                 }
     99 
    100                 // Right
    101                 rep(l, 0, k) {
    102                     val |= (1LL << colId[i+l][j+k]);
    103                 }
    104                 
    105                 sq.pb(val);
    106                 ++sz;
    107             }
    108         }
    109     }
    110 }
    111 
    112 void init() {
    113     rep(i, 1, 6)
    114         init_sq(i);
    115 }
    116 
    117 
    118 bool dfs(int m, LL cst) {
    119     const int& sz = sqInfo[n].sz;
    120     const vector<LL>& sq = sqInfo[n].sq;
    121     int h = 0;
    122     LL st = -1, tmp = cst;
    123     
    124     rep(i, 0, sz) {
    125         if ((tmp & sq[i]) == sq[i]) {
    126             ++h;
    127             tmp ^= sq[i];
    128             if (st < 0)
    129                 st = sq[i];
    130         }
    131     }
    132     
    133     if(h == 0)
    134         return true;
    135     
    136     if (m < h)
    137         return false;
    138     
    139     rep(i, 0, tot) {
    140         if (st & (1LL << i)) {
    141             if ( dfs(m-1, cst^(1LL<<i)) )    return true;
    142         }
    143     }
    144     return false;
    145 }
    146 
    147 void solve() {
    148     int ans = -1;
    149 
    150     for (int i=0; i<=tot; ++i) {
    151         if (dfs(i, st)) {
    152             ans = i;
    153             break;
    154         }
    155     }
    156 
    157     printf("%d
    ", ans);
    158 }
    159 
    160 int main() {
    161     ios::sync_with_stdio(false);
    162     #ifndef ONLINE_JUDGE
    163         freopen("data.in", "r", stdin);
    164         freopen("data.out", "w", stdout);
    165     #endif
    166 
    167     int t;
    168 
    169     init();
    170     scanf("%d", &t);
    171     while (t--) {
    172         scanf("%d", &n);
    173         tot = n*(n+1)*2;
    174         int k, x;
    175         st = (1LL << tot) - 1;
    176 
    177         scanf("%d", &k);
    178         while (k--) {
    179             scanf("%d", &x);
    180             --x;
    181             st ^= (1LL << x);
    182         }
    183         solve();
    184     }
    185 
    186     #ifndef ONLINE_JUDGE
    187         printf("time = %d.
    ", (int)clock());
    188     #endif
    189 
    190     return 0;
    191 }

    (2)Dancing Links

      1 /* 1084 */
      2 #include <iostream>
      3 #include <sstream>
      4 #include <string>
      5 #include <map>
      6 #include <queue>
      7 #include <set>
      8 #include <stack>
      9 #include <vector>
     10 #include <deque>
     11 #include <bitset>
     12 #include <algorithm>
     13 #include <cstdio>
     14 #include <cmath>
     15 #include <ctime>
     16 #include <cstring>
     17 #include <climits>
     18 #include <cctype>
     19 #include <cassert>
     20 #include <functional>
     21 #include <iterator>
     22 #include <iomanip>
     23 using namespace std;
     24 //#pragma comment(linker,"/STACK:102400000,1024000")
     25 
     26 #define sti                set<int>
     27 #define stpii            set<pair<int, int> >
     28 #define mpii            map<int,int>
     29 #define vi                vector<int>
     30 #define pii                pair<int,int>
     31 #define vpii            vector<pair<int,int> >
     32 #define rep(i, a, n)     for (int i=a;i<n;++i)
     33 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
     34 #define clr                clear
     35 #define pb                 push_back
     36 #define mp                 make_pair
     37 #define fir                first
     38 #define sec                second
     39 #define all(x)             (x).begin(),(x).end()
     40 #define SZ(x)             ((int)(x).size())
     41 #define lson            l, mid, rt<<1
     42 #define rson            mid+1, r, rt<<1|1
     43 #define INF                0x3f3f3f3f
     44 #define mset(a, val)    memset(a, (val), sizeof(a))
     45 
     46 #define LL __int64
     47 
     48 typedef struct {
     49     static const int maxr = 65;
     50     static const int maxc = 65;
     51     static const int maxn = maxr * maxc;
     52 
     53     int n, sz;
     54     int S[maxc];
     55     bool visit[maxc];
     56 
     57     int col[maxn];
     58     int L[maxn], R[maxn], U[maxn], D[maxn];
     59 
     60     int ansd;
     61 
     62     void init(int _n) {
     63         n = _n;
     64 
     65         rep(i, 0, n+1) {
     66             L[i] = i - 1;
     67             R[i] = i + 1;
     68             U[i] = i;
     69             D[i] = i;
     70             col[i] = i;
     71         }
     72 
     73         L[0] = n;
     74         R[n] = 0;
     75 
     76         sz = n + 1;
     77         memset(S, 0, sizeof(S));
     78         ansd = INF;
     79     }
     80 
     81     void addRow(const vi& columns) {
     82         int first = sz;
     83         int size = SZ(columns);
     84 
     85         rep(i, 0, size) {
     86             const int& c = columns[i];
     87 
     88             L[sz] = sz - 1;
     89             R[sz] = sz + 1;
     90 
     91             D[sz] = c;
     92             U[sz] = U[c];
     93             D[U[c]] = sz;
     94             U[c] = sz;
     95 
     96             col[sz] = c;
     97 
     98             ++S[c];
     99             ++sz;
    100         }
    101 
    102         L[first] = sz - 1;
    103         R[sz-1] = first;
    104     }
    105 
    106     void remove_col(int c) {
    107         for (int i=D[c]; i!=c; i=D[i]) {
    108             L[R[i]] = L[i];
    109             R[L[i]] = R[i];
    110             --S[col[i]];
    111         }
    112     }
    113 
    114     void restore_col(int c) {
    115         for (int i=D[c]; i!=c; i=D[i]) {
    116             L[R[i]] = i;
    117             R[L[i]] = i;
    118             ++S[col[i]];
    119         }
    120     }
    121 
    122     int H() {
    123         int ret = 0;
    124 
    125         memset(visit, false, sizeof(visit));
    126         for (int i=R[0]; i; i=R[i]) {
    127             if (visit[col[i]])
    128                 continue;
    129 
    130             ++ret;
    131             visit[col[i]] = true;
    132             for (int j=D[i]; j!=i; j=D[j]) {
    133                 for (int k=R[j]; k!=j; k=R[k]) {
    134                     visit[col[k]] = true;
    135                 }
    136             }
    137         }
    138 
    139         return ret;
    140     }
    141 
    142     void dfs(int d) {
    143         int delta = H();
    144 
    145         if (d+delta >= ansd)
    146             return ;
    147 
    148         if (R[0] == 0) {
    149             ansd = d;
    150             return ;
    151         }
    152 
    153         int c = R[0];
    154         for (int i=R[0]; i; i=R[i]) {
    155             if (S[i] < S[c])
    156                 c = i;
    157         }
    158 
    159         for (int i=D[c]; i!=c; i=D[i]) {
    160             remove_col(i);
    161             for (int j=R[i]; j!=i; j=R[j]) {
    162                 remove_col(j);
    163             }
    164             dfs(d + 1);
    165             for (int j=L[i]; j!=i; j=L[j]) {
    166                 restore_col(j);
    167             }
    168             restore_col(i);
    169         }
    170     }
    171 
    172 } DLX;
    173 
    174 typedef struct {
    175     vector<LL> sq;
    176     int sz;
    177 } sqInfo_t;
    178 
    179 DLX solver;
    180 const int maxm = 65;
    181 bool mark[maxm];
    182 int valid[maxm];
    183 int rowId[6][6];
    184 int colId[6][6];
    185 int n, tot;
    186 LL st;
    187 sqInfo_t sqInfo[6];
    188 
    189 void init_sq(int n) {
    190     int cnt = 0;
    191     sqInfo_t& info = sqInfo[n];
    192     vector<LL>& sq = info.sq;
    193     int& sz = info.sz;
    194 
    195     rep(i, 0, n) {
    196         rep(j, 0, n)
    197             rowId[i][j] = cnt++;
    198         rep(j, 0, n+1)
    199             colId[i][j] = cnt++;
    200     }
    201     rep(j, 0, n)
    202         rowId[n][j] = cnt++;
    203 
    204     cnt = 0;
    205     rep(i, 0, n) {
    206         rep(j, 0, n) {
    207             rep(k, 1, n+1) {
    208                 if (i+k>n || j+k>n)
    209                     break;
    210 
    211                 LL val = 0;
    212 
    213                 // Top
    214                 rep(l, 0, k) {
    215                     val |= (1LL << rowId[i][j+l]);
    216                 }
    217 
    218                 // Left
    219                 rep(l, 0, k) {
    220                     val |= (1LL << colId[i+l][j]);
    221                 }
    222 
    223                 // Down
    224                 rep(l, 0, k) {
    225                     val |= (1LL << rowId[i+k][j+l]);
    226                 }
    227 
    228                 // Right
    229                 rep(l, 0, k) {
    230                     val |= (1LL << colId[i+l][j+k]);
    231                 }
    232 
    233                 sq.pb(val);
    234                 ++sz;
    235             }
    236         }
    237     }
    238 }
    239 
    240 void init() {
    241     rep(i, 1, 6)
    242         init_sq(i);
    243 }
    244 
    245 void solve() {
    246     const vector<LL>& sq = sqInfo[n].sq;
    247     const int& sz = sqInfo[n].sz;
    248     int m = 0;
    249 
    250     rep(i, 0, sz) {
    251         if ((st & sq[i]) == sq[i]) {
    252             valid[m++] = i;
    253         }
    254     }
    255 
    256     if (m == 0) {
    257         puts("0");
    258         return ;
    259     }
    260 
    261     solver.init(m);
    262 
    263     rep(i, 0, tot) {
    264         if (mark[i]) {
    265             vi vc;
    266 
    267             rep(j, 0, m) {
    268                 if (sq[valid[j]] & (1LL << i))
    269                     vc.pb(j+1);
    270             }
    271 
    272             if (SZ(vc) > 0) {
    273                 solver.addRow(vc);
    274             }
    275         }
    276     }
    277 
    278     solver.dfs(0);
    279     int ans = solver.ansd;
    280 
    281     printf("%d
    ", ans);
    282 }
    283 
    284 int main() {
    285     ios::sync_with_stdio(false);
    286     #ifndef ONLINE_JUDGE
    287         freopen("data.in", "r", stdin);
    288         freopen("data.out", "w", stdout);
    289     #endif
    290 
    291     int t;
    292 
    293     init();
    294     scanf("%d", &t);
    295     while (t--) {
    296         scanf("%d", &n);
    297         memset(mark, true, sizeof(mark));
    298         tot = n*(n+1)*2;
    299         int k, x;
    300         st = (1LL << tot) - 1;
    301 
    302         scanf("%d", &k);
    303         while (k--) {
    304             scanf("%d", &x);
    305             mark[--x] = false;
    306             st ^= (1LL << x);
    307         }
    308         solve();
    309     }
    310 
    311     #ifndef ONLINE_JUDGE
    312         printf("time = %d.
    ", (int)clock());
    313     #endif
    314 
    315     return 0;
    316 }

    4. 数据生成器

     1 import sys
     2 import string
     3 from random import randint, shuffle
     4 
     5     
     6 def GenData(fileName):
     7     with open(fileName, "w") as fout:
     8         t = 20
     9         fout.write("%d
    " % (t))
    10         for tt in xrange(t):
    11             n = randint(1, 5)
    12             tot = n * (n + 1)
    13             taken = randint(1, tot)
    14             L = range(1, tot+1)
    15             shuffle(L)
    16             fout.write("%d %d
    " % (n, taken))
    17             fout.write(" ".join(map(str, L[:taken])) + "
    ")
    18             
    19             
    20 def MovData(srcFileName, desFileName):
    21     with open(srcFileName, "r") as fin:
    22         lines = fin.readlines()
    23     with open(desFileName, "w") as fout:
    24         fout.write("".join(lines))
    25 
    26         
    27 def CompData():
    28     print "comp"
    29     srcFileName = "F:Qt_prjhdojdata.out"
    30     desFileName = "F:workspacecpp_hdojdata.out"
    31     srcLines = []
    32     desLines = []
    33     with open(srcFileName, "r") as fin:
    34         srcLines = fin.readlines()
    35     with open(desFileName, "r") as fin:
    36         desLines = fin.readlines()
    37     n = min(len(srcLines), len(desLines))-1
    38     for i in xrange(n):
    39         ans2 = int(desLines[i])
    40         ans1 = int(srcLines[i])
    41         if ans1 > ans2:
    42             print "%d: wrong" % i
    43 
    44             
    45 if __name__ == "__main__":
    46     srcFileName = "F:Qt_prjhdojdata.in"
    47     desFileName = "F:workspacecpp_hdojdata.in"
    48     GenData(srcFileName)
    49     MovData(srcFileName, desFileName)
    View Code
  • 相关阅读:
    [Spring框架]Spring 事务管理基础入门总结.
    [Maven]Eclipse插件之Maven配置及问题解析.
    编程哲学的几点感悟
    用ASP.NET Core MVC 和 EF Core 构建Web应用 (十)
    用ASP.NET Core MVC 和 EF Core 构建Web应用 (九)
    C# 中的特性 Attribute
    用ASP.NET Core MVC 和 EF Core 构建Web应用 (八)
    用ASP.NET Core MVC 和 EF Core 构建Web应用 (七)
    C# 调用 WebApi
    用ASP.NET Core MVC 和 EF Core 构建Web应用 (六)
  • 原文地址:https://www.cnblogs.com/bombe1013/p/5322605.html
Copyright © 2011-2022 走看看