当前位置: 首页 > news >正文

UVa12418 Game of 999

UVa12418 Game of 999

  • 题目链接
  • 题意
  • 输入格式
  • 输出格式
  • 分析
  • AC 代码

题目链接

  UVa12418 Game of 999

题意

  注意,本题选材自 NDS 经典悬疑类密室逃脱游戏《9 小时9 人9 扇门》。本题不含任何剧透,只包含一些基本游戏规则的描述。这些规则和原游戏中的有所出入,请玩过游戏的读者仔细阅读题目。
  迷宫中有n(n≤10)个房间和m(m≤10)个连接它们的走廊。一些走廊的中部有一扇门,门上有一个1~9 的数字。走廊都是单向的,因此这些门也只能从一边打开。编号为 1∼91\sim919 的 9 个人一开始在房间 1 中,目标是从房间 n 中的出口逃脱。游戏规则如下。

  • 每扇门只能开一次。一旦有人通过,门将永远锁住。
  • 每扇门只能由 3~5 个人打开,而且这些人编号之和的数字根必须等于门上的数字。所谓数字根,即反复把各个数字加起来,直至得到一个一位数为止。例如,3,5,6,8 可以打开 4 号门,因为3+5+6+8=22,它的数字根为2+2=4。打开门的所有人都必须通过它,并且其他人都不能通过这扇门。

  你的任务是编写一个自动求解器,使得尽量多的人能够逃脱,在此前提下输出所有可能的逃脱组合。注意,每个房间可以多次进入(包括房间n),但一旦逃出迷宫,就不能再回到迷宫了。可以有多条走廊连接同一对房间,但不会有走廊的起点和终点是同一个房间。

输入格式

  输入包含多组测试数据。每组数据第第一行是两个整数 n,m(2≤n≤10,1≤m≤10)n,m(2≤n≤10,1≤m≤10)n,m(2n10,1m10),接下来 m 行每行三个整数 u,v,du,v,du,v,du,vu,vu,v 代表走廊的起点和终点,d=0d=0d=0 代表此走廊无门,d>0d>0d>0 则表示走廊有数字为 d 的门。

输出格式

  对于每组数据输出一行,先输出最多能逃脱的人数,再按字典序输出所有可能的逃脱组合,用空格分隔开。

分析

  可以先预处理数字根为 1∼91\sim919 各自包含的各种集合,预先打表存储,那么对每组数据求解时枚举到一个走廊时,一定是在对应数字根集合里面挑选起点内人员的子集,可以发现每个有门走廊的子集枚举量才37或38个。具体求解用 BFS,采用集合对状态判重即可通过了。

AC 代码

#include <iostream>
#include <set>
using namespace std;#define M 10
int g[M][38], c[M] = {0}, cc[512], u[M], v[M], d[M], m, n, cnt; bool ans[512];
struct node {int s[10], v;bool operator< (const node &r) const {if (v != r.v) return v < r.v;for (int i=0; i<n; ++i) if (s[i] != r.s[i]) return s[i] < r.s[i];return false;}
} q[200000], s;void print(int x) {cout << ' ';for (int i=8; i>=0; --i) if (x & 1<<i) cout << 9-i;
}void solve() {for (int i=0; i<512; ++i) ans[i] = false;for (int i=0; i<m; ++i) cin >> u[i] >> v[i] >> d[i], --u[i], --v[i];q[0].v = 0; q[0].s[0] = 511; for (int i=1; i<n; ++i) q[0].s[i] = 0;set<node> vis; vis.insert(q[0]);for (int h=cnt=0, t=1; h<t; ++h) {if (q[h].s[n-1]) {ans[q[h].s[n-1]] = true; cnt = max(cnt, cc[q[h].s[n-1]]);if (cnt == 9) break;}for (int i=0; i<m; ++i) if (~q[h].v & 1<<i && q[h].s[u[i]]) {if (d[i]) {for (int k=d[i], j=c[k]-1; j>=0; --j) if ((g[k][j] & q[h].s[u[i]]) == g[k][j]) {s = q[h]; s.s[u[i]] = q[h].s[u[i]] ^ g[k][j]; s.s[v[i]] |= g[k][j]; s.v |= 1<<i;if (!vis.count(s)) q[t++] = s, vis.insert(s);}} else for (int f=q[h].s[u[i]], ss=f; ss > 0; ss = (ss-1)&f) {s = q[h]; s.s[u[i]] = f ^ ss; s.s[v[i]] |= ss;if (!vis.count(s)) q[t++] = s, vis.insert(s);}}}cout << cnt;for (int i=511; i>0; --i) if (ans[i] && cc[i] == cnt) print(i);cout << endl;
}int main() {for (int i=1; i<512; ++i) {int k = 0, s = 0;for (int j=0; j<9; ++j) if (i & (1<<j)) ++k, s += 9-j;cc[i] = k;if (k > 2 && k < 6) {while (s > 9) s = s/10 + s%10;g[s][c[s]++] = i;}}while (cin >> n >> m) solve();return 0;
}
http://www.dtcms.com/a/405746.html

相关文章:

  • 基于51单片机的音乐弹奏系统
  • 负载均衡式的在线OJ项目编写(二)
  • 美篇在哪个网站做的外链代发工具
  • Linux高级技巧之集群部署(七)
  • 外贸做那种网站wordpress获取图片的绝对地址
  • 【自然语言处理与大模型】RAFT(Retrieval Augmented Fine Tuning)方法
  • 湖南网站建设公司 找磐石网络一流跨境电商平台app排名
  • 动态IP使用中 报错407 怎么办???
  • 手机百度建设网站台州企业网站建设
  • 鞍山网站建设制作新潮远网站建设
  • 网站友情链接的好处东莞专业微网站建设
  • 二级学院英语网站建设通知wordpress login网址
  • 计算机专业大学排名seo统计
  • 织梦网站怎么加入引导页成都最值得一去的地方
  • 手机网站需要什么c 网站开发需要学什么
  • 教人做美食视频网站wordpress开发上传图片
  • 做图网站有哪些注册网站给谁交钱
  • 昆明工程建设信息网站广元网站建设
  • 网站模板与网站定制版的区别服务商平台登录
  • 网站建设有什么出路赤壁市药监局网站建设方案
  • 怎么做下载类的网站吗域名官网
  • 怎么做域名网站wordpress 菜单路径
  • 进网站备案时间企业网站带后台
  • 网页超链接到别的网站404沈阳做网站公司有哪些
  • 东莞常平医院网站建设用dw做淘宝网站
  • 做网站需要哪些网站支付接口如何做
  • 个人网站建设案例教程网站域名哪里买
  • 门户网站后台管理模板宝安在深圳算什么档次
  • 开源手机建站系统北京专业网站设计公司
  • 怎么建网站新手入门中国建设银行网站成都第七支行