Problem 1686 神龙的难题
Accept: 860 Submit: 2548
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
这是个剑与魔法的世界.英雄和魔物同在,动荡和安定并存.但总的来说,库尔特王国是个安宁的国家,人民安居乐业,魔物也比较少.但是.总有一些魔物不时会进入城市附近,干扰人民的生活.就要有一些人出来守护居民们不被魔物侵害.魔法使艾米莉就是这样的一个人.她骑着她的坐骑,神龙米格拉一起消灭干扰人类生存的魔物,维护王国的安定.艾米莉希望能够在损伤最小的前提下完成任务.每次战斗前,她都用时间停止魔法停住时间,然后米格拉他就可以发出火球烧死敌人.米格拉想知道,他如何以最快的速度消灭敌人,减轻艾米莉的负担.
Input
Output
输出一行,一个整数,表示米格拉消灭所有魔物的最短时间.
Sample Input
4 41 0 0 10 1 1 00 1 1 01 0 0 12 24 4 0 0 0 00 1 1 00 1 1 00 0 0 02 2
Sample Output
41
题解: 找出所有的符合大小的矩阵,每个矩阵建立一行, 即求最少多少行能全部覆盖。 代码: #include<cstdio> #include<algorithm> using namespace std; const int maxn=1005; const int Maxn=1000005; int a[maxn][maxn],t[maxn][maxn]; struct node { int L[Maxn],R[Maxn],U[Maxn],D[Maxn]; int col[Maxn],row[Maxn]; int H[maxn],S[maxn]; int ansd,n,m,len; void init(int _n,int _m) { n=_n,m=_m; for(int i=0;i<=m;i++) { U[i]=D[i]=i; L[i]=i-1; R[i]=i+1; S[i]=0; } R[m]=0;L[0]=m;len=m;ansd=1e9; for(int i=1;i<=n;i++) H[i]=-1; } void Link(int r,int c) { D[++len]=D[c]; U[D[c]]=len; U[len]=c; D[c]=len; row[len]=r; col[len]=c; S[c]++; if(H[r]<0) H[r]=R[len]=L[len]=len; else { R[len]=R[H[r]]; L[R[H[r]]]=len; L[len]=H[r]; R[H[r]]=len; } } void remove(int c) { for(int i=D[c];i!=c;i=D[i]) { R[L[i]]=R[i]; L[R[i]]=L[i]; } } void resume(int c) { for(int i=U[c];i!=c;i=U[i]) { L[R[i]]=R[L[i]]=i; } } bool v[Maxn]; int f() { for(int i=R[0];i!=0;i=R[i]) v[i]=1; int ans=0; for(int i=R[0];i!=0;i=R[i]) { if(v[i]) { ans++; v[i]=0; for(int j=D[i];j!=i;j=D[j]) { for(int k=R[j];k!=j;k=R[k]) v[col[k]]=0; } } } return ans; } void Dance(int d) { if(d+f()>=ansd)return; if(R[0]==0) { ansd=min(ansd,d); return; } int c=R[0]; for(int i=R[0];i!=0;i=R[i]) { if(S[i]<S[c]) c=i; } for(int i=D[c];i!=c;i=D[i]) { remove(i); for(int j=R[i];j!=i;j=R[j]) remove(j); Dance(d+1); for(int j=L[i];j!=i;j=L[j]) resume(j); resume(i); } } }g; int main() { int n,m; while(~scanf("%d%d",&n,&m)) { int k=0; //memset(t,0,sizeof(t)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%d",&a[i][j]); if(a[i][j]) { k++; t[i][j]=k; } } int x,y; scanf("%d%d",&x,&y); g.init(n*m,k); k=0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { k++; for(int k1=0;k1<x;k1++) { for(int k2=0;k2<y;k2++) { int x1=i+k1,y1=j+k2; if(x1>=1&&x1<=n&&y1>=1&&y1<=m&&a[x1][y1]) { g.Link(k,t[x1][y1]); } } } } } g.Dance(0); printf("%d\n",g.ansd); } return 0; }