• UVA1374-Power Calculus(迭代加深搜索)


    Problem UVA1374-Power Calculus

    Accept:107  Submit:584

    Time Limit: 3000 mSec

     Problem Description

     Input

    The input consists of several test cases. The number of test cases (T) is given in the first line of the input file. Each test case consists of two lines: The first line contains a natural number n, not greater than 5, which implies you are given a (complete or incomplete) n×n grid as input, and the second line begins with a nonnegative integer k, the number of matchsticks that are missing from the complete n×n grid, followed by k numbers specifying the matchsticks. Note that if k is equal to zero, then the input grid is a complete n×n grid; otherwise, the input grid is an incomplete n×n grid such that the specified k matchsticks are missing from the complete n×n grid.

     Output

    Print exactly one line for each test case. The line should contain the minimum number of matchsticks that have to be taken out to destroy all the squares in the input grid.

     Sample Input

    2
    0
    3
    3 12 17 23
     

     Sample Ouput

    3

    3

    题解:IDA*算法,算法框架很简单,但是这个题的实现看上去就很困难,不超过60根火柴,因此用long long的二进制位来储存状态是很明智的,速度也比较快。

    预处理出所有正方形的状态,存到数组里,对于搜索到的每一个状态,拿这些正方形去比对,如果有完整的正方形,就说明还没到最终状态判断是否能剪枝后return false或者继续递归。

    剪枝挺粗暴的,如果有完整正方形,就把它的四个边全部去掉,但是h++,比对完之后,如果d+h还是大于maxd,那就必定要剪枝。

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <stdio.h>
      5 #include <cstdlib>
      6 
      7 using namespace std;
      8 typedef long long LL;
      9 
     10 const int maxn = 65;
     11 const int maxl = 10;
     12 
     13 LL sqr[maxn];
     14 LL one_sqr[maxl][maxl];
     15 
     16 int n,edge_cnt,sqr_cnt;
     17 int maxd;
     18 
     19 int get_hor(int r,int c){
     20     return (2*n+1)*r+c+1;
     21 }
     22 
     23 int get_ver(int r,int c){
     24     return (2*n+1)*r+c+n+1;
     25 }
     26 
     27 inline LL get_LL(int p){
     28     return (LL)1 << (p-1);
     29 }
     30 
     31 void init(){
     32     scanf("%d",&n);
     33     edge_cnt = 2*n*(n+1);
     34     sqr_cnt = 0;
     35     for(int i = 0;i < n;i++){
     36         for(int j = 0;j < n;j++){
     37             one_sqr[i][j] = get_LL(get_hor(i,j)) | get_LL(get_hor(i+1,j)) | get_LL(get_ver(i,j)) | get_LL(get_ver(i,j+1));
     38             sqr[sqr_cnt++] = one_sqr[i][j];
     39         }
     40     }
     41 
     42     for(int size = 2;size <= n;size++){
     43         for(int i = 0;i+size <= n;i++){
     44             for(int j = 0;j+size <= n;j++){
     45                 sqr[sqr_cnt] = 0;
     46                 for(int k = 0;k < size;k++)
     47                     for(int l = 0;l < size;l++)
     48                         sqr[sqr_cnt] ^= one_sqr[i+k][j+l];
     49                 sqr_cnt++;
     50             }
     51         }
     52     }
     53 }
     54 
     55 bool dfs(int d,LL s){
     56     LL t = s,sel = -1;
     57     int mind = 0;
     58     for(int i = 0;i < sqr_cnt;i++){
     59         if((t&sqr[i]) == sqr[i]){
     60             t ^= sqr[i];
     61             mind++;
     62             if(sel == -1) sel = sqr[i];
     63         }
     64     }
     65     if(sel == -1) return true;
     66     if(d+mind > maxd) return false;
     67 
     68     for(int j = 1;j <= edge_cnt;j++){
     69         if(sel & get_LL(j))
     70             if(dfs(d+1,s^(get_LL(j)))) return true;
     71     }
     72 
     73     return false;
     74 }
     75 
     76 int solve(){
     77     LL s = ((LL)1<<edge_cnt)-1;
     78     int t,x;
     79     scanf("%d",&t);
     80     while(t--){
     81         scanf("%d",&x);
     82         s ^= get_LL(x);
     83     }
     84 
     85     for(maxd = 0;;maxd++){
     86         if(dfs(0,s)) break;
     87     }
     88     return maxd;
     89 }
     90 
     91 int main()
     92 {
     93     int iCase;
     94 #ifdef GEH
     95     freopen("helloworld.01.inp","r",stdin);
     96 #endif
     97     scanf("%d",&iCase);
     98     while(iCase--){
     99         init();
    100         printf("%d
    ",solve());
    101     }
    102     return 0;
    103 }
  • 相关阅读:
    从缓冲上看阻塞与非阻塞socket在发送接收上的区别
    关于TCP封包、粘包、半包
    CURL 和LIBCURL C++代码 上传本地文件,好不容易碰到了这种折腾我几天的代码
    Spring boot 搭配 JPA 生成表注释 和 字段注释
    Spring Data JPA 中常用注解
    SpringBoot Data JPA 关联表查询的方法
    Spring boot data JPA数据库映射关系 : @OneToOne,@OneToMany,@ManyToMany
    Spring Boot Jpa 表名小写转大写
    SpringBoot入门系列~Spring-Data-JPA自动建表
    使用Spring-Session共享使用Session
  • 原文地址:https://www.cnblogs.com/npugen/p/9563826.html
Copyright © 2020-2023  润新知