题解 UVA1603 【Square Destroyer】
题目链接:Link
Solution
废话不说,先贴代码.....
#include<cstdio>
#include<cstring>
int n,m,maxd,cnt,sum;
int FullSize[625],Size[625];
bool sti[65],in[625][65];
inline int getc(int r,int c)// | 竖线
{
return r*(2*n+1)+c+n+1;
}
inline int getr(int r,int c)//-- 横线
{
return r*(2*n+1)+c+1;
}
inline int FindNext()//找到下一个没有破坏的正方形
{
for(int i=1;i<=cnt;i++)
if(Size[i]==FullSize[i])
return i;
return 0;
}
void dfs(int d)//深搜
{
if(d>=maxd) return;//最优性剪枝
int next=FindNext();
if(next==0)
{
maxd=d;
return;
}
for(int i=1;i<=sum;i++)
if(in[next][i])
{
for(int j=1;j<=cnt;j++)//删掉火柴棍
if(in[j][i]) Size[j]--;
dfs(d+1);
for(int j=1;j<=cnt;j++)//复原
if(in[j][i]) Size[j]++;
}
}
int main()
{
#ifdef local
freopen("pro.in","r",stdin);
#endif
int kase;
scanf("%d",&kase);
while(kase-->0)
{
memset(in,0,sizeof(in));
memset(sti,1,sizeof(sti));
cnt=0;
scanf("%d%d",&n,&m);
int a,b,e,f;
for(int i=0;i<m;i++)
{
scanf("%d",&a);
sti[a]=0;
}
//状态压缩+预处理
for(int len=1;len<=n;len++)
for(int r=0;r+len<=n;r++)
for(int c=0;c+len<=n;c++)
{
cnt++;
FullSize[cnt]=len*4;
Size[cnt]=0;
for(int i=0;i<len;i++)
{
a=getr(r,c+i);
b=getr(r+len,c+i);
e=getc(r+i,c);
f=getc(r+i,c+len);
in[cnt][a]=true;
in[cnt][b]=true;
in[cnt][e]=true;
in[cnt][f]=true;
Size[cnt]+=sti[a]+sti[b]+sti[e]+sti[f];
}
}
maxd=n*n;//设置上限
sum=2*n*(n+1);
dfs(0);
printf("%d\n",maxd);
}
return 0;
}
本作品由happyZYM采用知识共享 署名-非商业性使用-相同方式共享 4.0 (CC BY-NC-SA 4.0) 国际许可协议(镜像(简单版)镜像(完整版))进行许可。
转载请注明出处:https://www.cnblogs.com/happyZYM/p/11379996.html (近乎)全文转载而非引用的请在文首添加出处链接。