zoukankan      html  css  js  c++  java
  • ZOJ 3209 Treasure Map

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3209

    dancing links 每个点作为一列。

    每个块作为一行。

    不知道为什么插节点的时候 如果把循环写成

    for(int i = y1+1; i <= y2; i++){      //行 
                  for(int j = x1+1; j <= x2; j++){ //列 
          
                  }
              }
    然后col = (y-1)*n+x就会超时。
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <string>
      5 #include <iomanip>
      6 using namespace std;
      7 int T, n, m, p, x1, y1, x2, y2;
      8 #define maxn 510*35*35
      9 int R[maxn], L[maxn], U[maxn], D[maxn];
     10 int H[maxn], C[maxn], colsum[999];
     11 int head, cnt, ans;
     12 void addnode(int i, int j, int h, int rowhead, int sum, int pre){
     13     int col = j+(i-1)*m; //cout<<col<<" ";
     14     cnt++;
     15     
     16     H[cnt] = h; C[cnt] = col;
     17     if(sum == 1){
     18         R[cnt] = cnt; L[cnt] = cnt;
     19     }
     20     else if(sum == 2){
     21         R[pre] = cnt; R[cnt] = pre;
     22         L[pre] = cnt; L[cnt] = pre; 
     23     }
     24     else{
     25         R[cnt] = rowhead; R[pre] = cnt;
     26         L[cnt] = pre; L[rowhead] = cnt;
     27     }
     28     
     29     D[U[col]] = cnt;
     30     U[cnt] = U[col];
     31     D[cnt] = col;
     32     U[col] = cnt;
     33     
     34     colsum[col]++; 
     35     
     36 }
     37 void init(){
     38     head = cnt = 0;
     39     ans = 510;  //最多就是500块。 
     40     R[head] = 1; L[head] = n*m; U[head] = head; D[head] = head;
     41     H[head] = 0; C[head] = 0;
     42     memset(colsum, 0, sizeof(colsum));
     43     for(int i = 1; i <= n*m; i++){
     44         cnt++;
     45         U[cnt] = D[cnt] = cnt;
     46         H[cnt] = 0; C[cnt] = i;
     47         if(i == n*m){
     48             R[cnt-1] = cnt; L[cnt] = cnt-1; R[cnt] = head;
     49         }    
     50         else{
     51             R[cnt-1] = cnt; L[cnt] = cnt-1;    
     52         }
     53     }
     54     for(int cc = 1; cc <= p; cc++){
     55         scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
     56         int sum = 0, rowhead = -1, pre;
     57         for(int i = x1+1; i <= x2; i++){      //
     58             for(int j = y1+1; j <= y2; j++){ //
     59                 sum++;
     60                 addnode(i, j ,cc, rowhead, sum, pre);
     61                 if(rowhead == -1) rowhead = cnt;
     62                 pre = cnt;
     63             }
     64         }
     65     }
     66 }
     67 void remove(int c){
     68     R[L[c]] = R[c]; L[R[c]] = L[c];
     69     for(int i = D[c]; i != c; i = D[i]){
     70         for(int j = R[i]; j != i; j = R[j]){
     71             U[D[j]] = U[j]; D[U[j]] = D[j];
     72             colsum[C[j]]--;
     73         }
     74     }
     75 }
     76 void resume(int c){
     77     R[L[c]] = c; L[R[c]] = c;
     78     for(int i = D[c]; i != c; i = D[i]){
     79         for(int j = R[i]; j != i; j = R[j]){
     80             U[D[j]] = j; D[U[j]] = j;
     81             colsum[C[j]]++;
     82         }
     83     }
     84 }
     85 void dance(int k){
     86     if(k >= ans) return;
     87     int c = R[head];
     88     if(c == head){
     89         ans = k;
     90         return;
     91     }
     92     int min = 9999999;
     93     for(int i = R[head]; i != head; i = R[i]){
     94         if(colsum[i] <= min){
     95             min = colsum[i]; c = i;
     96         }
     97     }
     98     remove(c);
     99     for(int i = D[c]; i != c; i = D[i]){
    100         for(int j = R[i]; j != i; j = R[j]) remove(C[j]);
    101         dance(k+1);
    102         for(int j = L[i]; j != i; j = L[j]) resume(C[j]); //要写成L 
    103     }
    104     resume(c);
    105     return ;
    106 }
    107 int main(){
    108     scanf("%d", &T);
    109     while(T--){
    110         scanf("%d%d%d", &n, &m, &p); //n是列,m是行。 
    111         init();
    112         dance(0);
    113         if(ans == 510) printf("-1
    ");
    114         else printf("%d
    ", ans);
    115     }
    116     
    117     return 0;
    118 }
  • 相关阅读:
    windows下的IO模型之选择(select)模型
    tcp通讯中socket套接字accept和listen的关系
    转一篇shell中关于各种括号的讲解
    记两个std接口equal_range,set_difference
    nginx学习
    c++ 读取文本问题
    vim使用常看
    CNN设计一些问题
    什么是反射?反射机制的应用场景有哪些?
    java为什么只有值传递?
  • 原文地址:https://www.cnblogs.com/titicia/p/4452285.html
Copyright © 2011-2022 走看看