UVa1603-Square Destroyer
Question:
Given a square array of matchsticks, remove some matchsticks, and ask if at least a few more matchsticks are removed so that no square is in the figure.
Ideas:
1. Given the range of n in the question, 2 * n * (n + 1) <= 60-> can ensure that all matches are represented by a bit of _ int64;
2. The key to the problem is how to generate a square matrix consisting of matches and how to search after the square matrix is generated;
3. calculation of heuristic function h requires consideration: if an edge of a matrix is deleted, h (s1) <= h (s2) + C (s1, s2) can be ensured ), where C (s1, s2) = 1, h (s1)-h (s2) <= 1, which can be proved by Reverse verification;
4. The range of bitwise operations should be clear, for example, 1 <
Zishu analysis: iterative deep search is the main algorithm framework. There are two types of search objects,
1. every time you think about a square that has not been damaged, find a match on the boundary to take it away. The search object is a square. You should first consider a small square and draw a square in the examination, because after a small square is destroyed, the big positive square is destroyed, but in turn it is not necessarily. We can also add the optimum branch to consider each square as a vertex, if a square with a public match is connected to an edge, each connected component should take at least one match.
2. Find a match that can damage at least one square each time and remove it. When the search object is a match, you should search for matches that can damage the most squares as much as possible. This requires calculating the number of squares that can be damaged by each match, sort d [1] in ascending order... when d [1] is 1, the search can be stopped because the number of matches is calculated directly. This d array can also be used to reduce the number of necessary matches and find the smallest I, make d [1] + d [2] =... + d [I] <= k (where k is the number of squares that are also saved), at least I and match are required.
It can also be solved using the DLX algorithm.
#include
#include#include
#include
using namespace std;const int INFS = 0x7fffffff;int N,C,E,bound;__int64 square[100], base[6][6];bool succ;inline int __int64 getflag(int i){ return ((__int64)1<<(i-1));}inline int geth(int i,int j){ return (2*N+1)*(i-1)+j;}inline int getv(int i,int j){ return (2*N+1)*(i-1)+j+N;}void build(){ C=0; memset(base,0,sizeof(base)); for(int i=1;i<=N;i++){ for(int j=1;j<=N;j++){ base[i][j] |= getflag(geth(i,j)) | getflag(geth(i+1,j)); base[i][j] |= getflag(getv(i,j)) | getflag(getv(i,j+1)); square[C++] = base[i][j]; } } for(int size=2;size<=N;size++){ for(int i=1;i+size-1 <= N;i++){ for(int j=1;j+size-1<=N;j++){ square[C]=0; for(int a=0;a
bound){ return depth+h; } int newbound = INFS; for(int i=1;i<=E;i++){ if(u & getflag(i)){ int b=dfs(state ^ getflag(i),depth+1); if(succ) return b; newbound = min(b,newbound); } } return newbound;}int main(){ int cases; scanf("%d",&cases); while(cases--){ scanf("%d",&N); build(); E = 2*N*(N+1); int k; __int64 state = ((__int64)1<