fzu-神龙的难题 舞蹈链之可重复覆盖

这是个剑与魔法的世界.英雄和魔物同在,动荡和安定并存.但总的来说,库尔特王国是个安宁的国家,人民安居乐业,魔物也比较少.但是.总有一些魔物不时会进入城市附近,干扰人民的生活.就要有一些人出来守护居民们不被魔物侵害.魔法使艾米莉就是这样的一个人.她骑着她的坐骑,神龙米格拉一起消灭干扰人类生存的魔物,维护王国的安定.艾米莉希望能够在损伤最小的前提下完成任务.每次战斗前,她都用时间停止魔法停住时间,然后米格拉他就可以发出火球烧死敌人.米格拉想知道,他如何以最快的速度消灭敌人,减轻艾米莉的负担.
Input

数据有多组,你要处理到EOF为止.每组数据第一行有两个数,n,m,(1<=n,m<=15)表示这次任务的地区范围. 然后接下来有n行,每行m个整数,如为1表示该点有怪物,为0表示该点无怪物.然后接下一行有两个整数,n1,m1 (n1<=n,m1<=m)分别表示米格拉一次能攻击的行,列数(行列不能互换),假设米格拉一单位时间能发出一个火球,所有怪物都可一击必杀.

Output

输出一行,一个整数,表示米格拉消灭所有魔物的最短时间.

Sample Input
4 4
1 0 0 1
0 1 1 0
0 1 1 0
1 0 0 1
2 2
4 4 
0 0 0 0
0 1 1 0
0 1 1 0
0 0 0 0
2 2
Sample Output
4

1

好久不见得中文题,可谓一股清流啊,由于刚接触舞蹈链说实话只是刚刚会套个模板而已,但看到这个题就蒙了,因为对于如何构造矩阵一头雾水,在翻阅了多个大神博客后才晓得以所给矩阵中的1为列(当然需要给1标号),然后以所给攻击范围的规模大小的矩阵为行,刚开始还不太明白,但后来明白了,其实如何确定矩阵很简单,首先咱们在模板的原型中要明白是找出几行然后使得每列中至少含有一个1(覆盖所有列),然后咱们再分析本题,本题是问最少攻击几次能把敌人全部消灭,每次攻击是一个给定规模的矩阵,所以简单点看就是让我们找最少的矩阵能覆盖所有1,那么矩阵的行列就好确定了,矩阵为行,1为列

ac代码:

#include <vector> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3fll; const int maxn=260; int L[maxn*maxn],R[maxn*maxn],U[maxn*maxn],D[maxn*maxn];//节点的上下左右四个方向的链表 int C[maxn*maxn],H[maxn],cnt[maxn],vis[maxn];//C列H行cnt列链表中元素个数 int n,m,id,fans; void init(int ll){     for(int i=0;i<=ll;i++){         cnt[i]=0;U[i]=D[i]=i;         L[i+1]=i;R[i]=i+1;     }     R[ll]=0;id=ll+1;     memset(H,-1,sizeof(H)); } void Link(int r,int c){     cnt[c]++;C[id]=c;     U[id]=U[c];D[U[c]]=id;     D[id]=c;U[c]=id;     if(H[r]==-1) H[r]=L[id]=R[id]=id;     else{         L[id]=L[H[r]];R[L[H[r]]]=id;         R[id]=H[r];L[H[r]]=id;     }     id++; } void Remove(int Size){     for(int j=D[Size];j!=Size;j=D[j])         L[R[j]]=L[j],R[L[j]]=R[j]; } void Resume(int Size){     for(int j=D[Size];j!=Size;j=D[j])         L[R[j]]=R[L[j]]=j; } int h(){     int sum=0;     memset(vis,0,sizeof(vis));     for(int i=R[0];i;i=R[i]){         if(vis[i]) continue;         sum++;         for(int j=D[i];j!=i;j=D[j]){             for(int k=R[j];k!=j;k=R[k])                 vis[C[k]]=1;         }     }     return sum; } void Dance(int k){     int mm=maxn,pos;     if(k+h()>=fans) return;     if(!R[0]){         if(k<fans) fans=k;         return;     }     for(int i=R[0];i;i=R[i])         if(mm>cnt[i]) mm=cnt[i],pos=i;     for(int i=D[pos];i!=pos;i=D[i]){         Remove(i);         for(int j=R[i];j!=i;j=R[j]) Remove(j);         Dance(k+1);         for(int j=R[i];j!=i;j=R[j]) Resume(j);         Resume(i);     } } int A[20][20],B[20][20]; int main(){     int u,v,len,wid;     while(scanf("%d%d",&n,&m)!=-1){         int kk=0,kkk=1;         for(int i=1;i<=n;i++)         for(int j=1;j<=m;j++){             scanf("%d",&A[i][j]);             if(A[i][j]==1) B[i][j]=(++kk);//给1编号         }         scanf("%d%d",&len,&wid);         init(kk);         for(int i=1;i<=n-len+1;i++){             for(int j=1;j<=m-wid+1;j++){                 for(int k=0;k<len;k++){                     for(int l=0;l<wid;l++){                         if(A[i+k][j+l]==1) Link(kkk,B[i+k][j+l]);                     }                 }                 kkk++;//矩阵个数             }         }         fans=kkk-1;         Dance(0);         printf("%d\n",fans);     }     return 0; }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 JavaScript 编写的记忆游戏(附源代码)   项目:JavaScript 记忆游戏(附源代码) 记忆检查游戏是一个使用 HTML5、CSS 和 JavaScript 开发的简单项目。这个游戏是关于测试你的短期 记忆技能。玩这个游戏 时,一系列图像会出现在一个盒子形状的区域中 。玩家必须找到两个相同的图像并单击它们以使它们消失。 如何运行游戏? 记忆游戏项目仅包含 HTML、CSS 和 JavaScript。谈到此游戏的功能,用户必须单击两个相同的图像才能使它们消失。 点击卡片或按下键盘键,通过 2 乘 2 旋转来重建鸟儿对,并发现隐藏在下面的图像! 如果翻开的牌面相同(一对),您就赢了,并且该对牌将从游戏中消失! 否则,卡片会自动翻面朝下,您需要重新尝试! 该游戏包含大量的 javascript 以确保游戏正常运行。 如何运行该项目? 要运行此游戏,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox, 以获得更好、更优化的游戏体验。要玩游戏,首先,通过单击 memorygame-index.html 文件在浏览器中打开游戏。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值