zoukankan      html  css  js  c++  java
  • UVA 1603 Square Destroyer

    https://vjudge.net/problem/UVA-1603

    题目

    The left figure below shows a complete$3 imes 3$grid made with2$ imes(3 imes 4)$(=24) matchsticks. The lengthsof all matchsticks are one. You can find many squares of different sizes in the grid. The size of a squareis the length of its side. In the grid shown in the left figure, there are 9 squares of size one, 4 squaresof size two, and 1 square of size three.Each matchstick of the complete grid is identified with a unique number which is assigned from leftto right and from top to bottom as shown in the left figure. If you take some matchsticks out from thecomplete grid, then some squares in the grid will be destroyed, which results in an incomplete $3 imes 3$ grid. The right figure illustrates an incomplete $3 imes 3$ grid after removing three matchsticks numberedwith 12, 17 and 23. This removal destroys 5 squares of size one, 3 squares of size two, and 1 square of size three. Consequently, the incomplete grid does not have squares of size three, but still has 4 squaresof size one and 1 square of size two.

    As input, you are given a (complete or incomplete) $n  imes n$ grid made with no more than $2n(n + 1)$ matchsticks for a natural number $n leqslant 5$. Your task is to compute the minimum number of matchsticks taken out to destroy all the squares existing in the input $n  imes n$ grid.

    题解

    做这个题做到自闭……

    首先判断正方形的部分就不好写(写了3小时)……然后搜索的复杂度也猜不出来,状态数高达$2 ^ {220}$,BFS存不下状态

    换用迭代加深搜,一直TLE

    TLE代码

    #include<bits/stdc++.h>
    using namespace std;
    #define REP(i,x,y) for(register int i=(x); i<(y); i++)
    #define REPE(i,x,y) for(register int i=(x); i<=(y); i++)
    #define MAXN 30
    #ifdef sahdsg
    #define DBG(...) printf(__VA_ARGS__);
    #else
    #define DBG(...)
    #endif
    typedef pair<int,int> pii;
    bool arr[220];
    int md;
    int n,tot;
    int counter(bool *arr, pii *stick) {
    	int s=0;
    	bool k=true;
    	k=true;
    	REPE(sz,1,n) {
    		REPE(ax,0,n-sz) REPE(ay,0,n-sz) {
    			k=true;
    			REP(i,0,sz) {
    				if(arr[ax+ay*(n+n+1)+i]) {
    					k=false;
    					break;
    				}
    			}
    			if(k)REP(i,0,sz) {
    				if(arr[ax+(ay+i)*(n+n+1)+n] || arr[ax+(ay+i)*(n+n+1)+n+sz]) {
    					k=false;
    					break;
    				}
    			}
    			if(k)REP(i,0,sz) {
    				if(arr[ax+(ay+sz)*(n+n+1)+i]) {
    					k=false;
    					break;
    				}
    			}
    			if(k){
    				s++;
    				REPE(bx,0,n-sz) REPE(by,0,n-sz) {
    					REP(i,0,sz) {
    						stick[bx+by*(n+n+1)+i].first++;
    					}
    					REP(i,0,sz) {
    						stick[bx+(by+i)*(n+n+1)+n].first++;
    						stick[bx+(by+i)*(n+n+1)+n+sz].first++;
    					}
    					REP(i,0,sz) {
    						stick[bx+(by+sz)*(n+n+1)+i].first++;
    					}
    				}
    			}
    		}
    		
    	}
    	return s;
    }
    bool solve(int d, bool *oarr) {
    	pii stick[220];
    	REP(i,0,tot) stick[i].second=i,stick[i].first=0;
    	int s=counter(oarr,stick);
    	if(s==0) return true;
    	sort(stick,stick+tot,greater<pii>());
    	
    	if(stick[0].first==1) {
    		md+=s;
    		return true;
    	}
    	int sum=0, k=999999;
    	REP(i,0,tot) {
    		sum+=stick[i].first;
    		if(sum>=s) {k=i+1; break;}
    	}
    	if(k+d>md) return false;
    	REP(i,0,tot) {
    		if(oarr[stick[i].second]) continue;
    		oarr[stick[i].second]=1;
    		if(solve(d+1,oarr)) return true;
    		oarr[stick[i].second]=0;
    	}
    	return 0;
    }
    int main() {
    #ifdef sahdsg
    	freopen("in.txt", "r", stdin);
    #endif
    	int T;
    	scanf("%d",&T);
    	while(0<T--) {
    		scanf("%d",&n);
    		tot=2*n*(n+1);
    		int d;
    		scanf("%d",&d);
    		memset(arr,0,sizeof arr);
    		REP(i,0,d) {
    			int t;
    			scanf("%d",&t);
    			arr[t]=1;
    		}
    		for(md=0; ; md++) {
    			DBG("#%d", md);
    			if(solve(0,arr)) {
    				printf("%d
    ", md);
    				break;
    			}
    		}
    	}
    	return 0;
    }
    

    看了答案 最重要的判断正方形的部分太慢了……

    需要预处理,对每个正方形编号,然后保存每个完整正方形的火柴数目,然后维护正方形的实时火柴棍数目,或者使用DLX算法

    (今天去听大学的意义的讲座,也是服了,为什么要去听这种讲座浪费人参啊……)

  • 相关阅读:
    mac下用xattr命令来删除文件的扩展属性
    使用vue.js实现checkbox的全选和多个的删除功能
    正则表达式匹配任意字符(包括换行符)的写法
    jQuery Mobile动态刷新页面样式
    jquery mobile各类标签的refresh
    jQuery .attr()和.removeAttr()方法操作元素属性示例
    jquery mobile各类组件刷新方法
    Apache PDFbox开发指南之PDF文档读取
    日期字符串解析--SimpleDateFormat严格限制日期转换setLenient(false)
    hdu5032 Always Cook Mushroom
  • 原文地址:https://www.cnblogs.com/sahdsg/p/10459064.html
Copyright © 2011-2022 走看看