Description

题库链接

两个人 Van♂ 游戏,每人手上各有 \(8\) 张牌,牌上数字均为 \([0,4]\) 之间的数。每个人在自己的回合选自己手牌中数字不为 \(0\) 的一张与对方手牌中不为 \(0\) 的一张。数字相加对 \(5\) 取模,赋给自己当前选中的这张牌。 \(T\) 组询问,给出先手,问谁能胜。

\(1\leq T\leq 100000\)

Solution

首先注意到卡牌顺序是没有影响的,我们可以按数字大小排序。这时由可重复的组合得每个人可能的方案只有 \(\binom{8+5-1}{8}=495\) 种。所以两个人不同的状态共 \(495^2=245025\) 种。

我们可以将每个状态抽象成节点,节点存下两个状态,改轮的操作者的状态和对方的状态。用有向边链接操作前的和操作后的情况。我们可以用 \(O\left(8^2\cdot\binom{8+5-1}{8}^2\right)\) 来枚举所有状态建边。对于每个节点我们考虑其连向的所有节点:

  1. 若存在一个连向的节点的状态能够保证当前的后手必败,那么改轮的操作者必胜;
  2. 若其连向的所有节点都是必胜,该节点必败;
  3. 其余的情况,则是平局。

我们可以通过反向建边 \(topsort\) 来实现。 \(O(1)\) 回答询问。

Code

  1. //It is made by Awson on 2018.2.2
  2. #include <bits/stdc++.h>
  3. #define LL long long
  4. #define dob complex<double>
  5. #define Abs(a) ((a) < 0 ? (-(a)) : (a))
  6. #define Max(a, b) ((a) > (b) ? (a) : (b))
  7. #define Min(a, b) ((a) < (b) ? (a) : (b))
  8. #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
  9. #define writeln(x) (write(x), putchar('\n'))
  10. #define lowbit(x) ((x)&(-(x)))
  11. using namespace std;
  12. const int N = 400000;
  13. void read(int &x) {
  14. char ch; bool flag = 0;
  15. for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
  16. for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
  17. x *= 1-2*flag;
  18. }
  19. void print(int x) {if (x > 9) print(x/10); putchar(x%10+48); }
  20. void write(int x) {if (x < 0) putchar('-'); print(Abs(x)); }
  21. int S[N+5], C[N+5], cnt;
  22. struct hs {
  23. int a[8];
  24. hs() {memset(a, 0, sizeof(a)); }
  25. hs(int x) {for (int i = 7; i >= 0; i--) a[i] = x%5, x /= 5; }
  26. hs(int *_a) {for (int i = 0; i < 8; i++) a[i] = _a[i]; }
  27. void rd() {for (int i = 0; i < 8; i++) read(a[i]); }
  28. void st() {sort(a, a+8); }
  29. int hash() {
  30. int ans = 0;
  31. for (int i = 0; i < 8; i++) ans = ans*5+a[i];
  32. return ans;
  33. }
  34. };
  35. struct tt {int to, next; }edge[(N<<6)+5];
  36. int path[N+5], top, in[N+5], ans[N+5];
  37. void add(int u, int v) {++in[v]; edge[++top].to = v, edge[top].next = path[u]; path[u] = top; }
  38. int no(int a, int b) {return (a-1)*cnt+b-1; }
  39. void dfs(int cen, int last, int h) {
  40. if (cen == 8) {S[++cnt] = h, C[h] = cnt; return; }
  41. for (int i = last; i < 5; i++) dfs(cen+1, i, h*5+i);
  42. }
  43. void prework() {
  44. dfs(0, 0, 0);
  45. for (int i = 1; i <= cnt; i++)
  46. for (int j = 1; j <= cnt; j++) {
  47. hs a(S[i]), b(S[j]);
  48. for (int p = 0; p < 8; p++) if (a.a[p])
  49. for (int q = 0; q < 8; q++) if (b.a[q]) {
  50. hs c(a.a);
  51. c.a[p] = (a.a[p]+b.a[q])%5;
  52. c.st(); int tmp = C[c.hash()];
  53. add(no(j, tmp), no(i, j));
  54. }
  55. }
  56. queue<int>Q; while (!Q.empty()) Q.pop();
  57. for (int i = 2; i <= cnt; i++) ans[no(i, 1)] = 1, Q.push(no(i, 1));
  58. while (!Q.empty()) {
  59. int u = Q.front(); Q.pop();
  60. for (int i = path[u]; i; i = edge[i].next) if (!ans[edge[i].to]) {
  61. if (ans[u] == 1) {ans[edge[i].to] = -1; Q.push(edge[i].to); }
  62. else if (--in[edge[i].to] == 0) {
  63. Q.push(edge[i].to); ans[edge[i].to] = 1;
  64. }
  65. }
  66. }
  67. }
  68. void work() {
  69. prework();
  70. int t, f; hs a, b; read(t);
  71. while (t--) {
  72. read(f); a.rd(), b.rd(); a.st(); b.st();
  73. if (f) swap(a, b);
  74. int as = ans[no(C[a.hash()], C[b.hash()])];
  75. if (as == 0) puts("Deal");
  76. else if (as == -1 && f || as == 1 && !f) puts("Bob");
  77. else puts("Alice");
  78. }
  79. }
  80. int main() {
  81. work();
  82. return 0;
  83. }

[Codeforces 919F]A Game With Numbers的更多相关文章

  1. Codeforces 919F. A Game With Numbers(博弈论)

      Imagine that Alice is playing a card game with her friend Bob. They both have exactly 88 cards and ...

  2. 【题解】 Codeforces 919F A Game With Numbers(拓扑排序+博弈论+哈希)

    懒得复制,戳我戳我 Solution: 我感觉我也说不太好,看Awson的题解吧. 说一点之前打错的地方: 连边存的是hash后的数组下标 if(ans[ num( C[a.hash()] , C[b ...

  3. Codeforces 919F——A Game With Numbers

    转自大佬博客:https://www.cnblogs.com/NaVi-Awson/p/8405966.html; 题意 两个人 Van♂ 游戏,每人手上各有 8'>88 张牌,牌上数字均为 [ ...

  4. Codeforces 385C Bear and Prime Numbers

    题目链接:Codeforces 385C Bear and Prime Numbers 这题告诉我仅仅有询问没有更新通常是不用线段树的.或者说还有比线段树更简单的方法. 用一个sum数组记录前n项和, ...

  5. Codeforces 385C Bear and Prime Numbers(素数预处理)

    Codeforces 385C Bear and Prime Numbers 其实不是多值得记录的一道题,通过快速打素数表,再做前缀和的预处理,使查询的复杂度变为O(1). 但是,我在统计数组中元素出 ...

  6. Educational Codeforces Round 2 A. Extract Numbers 模拟题

    A. Extract Numbers Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/600/pr ...

  7. Educational Codeforces Round 8 D. Magic Numbers 数位DP

    D. Magic Numbers 题目连接: http://www.codeforces.com/contest/628/problem/D Description Consider the deci ...

  8. codeforces 556B. Case of Fake Numbers 解题报告

    题目链接:http://codeforces.com/problemset/problem/556/B 题目意思:给出 n 个齿轮,每个齿轮有 n 个 teeth,逆时针排列,编号为0 ~ n-1.每 ...

  9. codeforces 446C DZY Loves Fibonacci Numbers(数学 or 数论+线段树)(两种方法)

    In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence relation F1 ...

随机推荐

  1. 利用jmeter进行数据库测试

    1.首先,用jmeter进行数据库测试之前,要把oracle和mysql的JDBC驱动jar包放到jmeter安装路径的lib目录下,否则会提示错误 2.添加一个线程组,如下图 3.接下来添加一个JD ...

  2. 转git取消commit

     如果不小心commit了一个不需要commit的文件,可以对其进行撤销. 先使用git log 查看 commit日志 commit 422bc088a7d6c5429f1d0760d008d8 ...

  3. JAVA反射机制基础概念

    反射机制:所谓的反射机制就是java语言在运行时拥有一项自观的能力.通过这种能力可以彻底的了解自身的情况为下一步的动作做准备.下面具体介绍一下java的反射机制.这里你将颠覆原来对java的理解. J ...

  4. Linux下ip配置与网络重启

    ip配置 //以下ip配置重启失效 sudo ifconfig 192.168.1.1 sudo ifconfig 192.168.1.1 netmask 255.255.255.0 网络重启 //关 ...

  5. python的项目结构

    项目结构 知识点 创建项目,编写 __init__ 文件 使用 setuptools 模块,编写 setup.py 和 MANIFEST.in 文件 创建源文件的发布版本 项目注册&上传到 P ...

  6. ios中录音功能的实现AudioSession的使用

    这个星期我完成了一个具有基本录音和回放的功能,一开始也不知道从何入手,也查找了很多相关的资料.与此同时,我也学会了很多关于音频方面的东西,这也对后面的录音配置有一定的帮助.其中参照了<iPhon ...

  7. github感悟

    刚学GitHub进入网页全英文的,感觉很惊讶,自己竟然要在全英文的网站上学习,虽然是英文的但并不感觉有压力,可能之前用eclipse就是全英文的现在除了惊讶,没太多的想法.然后就是我的GitHub地址 ...

  8. Autowired注解

    package com.how2java.pojo; import org.springframework.beans.factory.annotation.Autowired; public cla ...

  9. 第二篇:Python数据类型

    一.引子 1.什么是数据? x= #是我们要存储的数据 2.为何数据要分不同的类型 数据是用来表示状态的,不同的状态就应该用不同的类型的数据去表示 3.数据类型 数字(整型,长整型,浮点型,复数) 字 ...

  10. NFC驱动调试

    1.NFC基本概念: NFC 又称为近场通信,是一种新兴技术,可以在彼此靠近的情况下进行数据交换,是由非接触式射频识别(RFID) 及互连互通技术整合演变而来,通过单一芯片集成感应式读卡器: NFC有 ...