「NOI2017」游戏

题目描述

小 L 计划进行 \(n\) 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏。

小 L 的赛车有三辆,分别用大写字母 \(A\)、\(B\)、\(C\) 表示。地图一共有四种,分别用小写字母 \(x\)、\(a\)、\(b\)、\(c\) 表示。

其中,赛车 \(A\) 不适合在地图 \(a\) 上使用,赛车 \(B\) 不适合在地图 \(b\) 上使用,赛车 \(C\) 不适合在地图 \(c\) 上使用,而地图 \(x\) 则适合所有赛车参加。适合所有赛车参加的地图并不多见,最多只会有 \(d\) 张。

小 L 对游戏有一些特殊的要求,这些要求可以用四元组 \((i, h_i, j, h_j)\) 来描述,表示若在第 \(i\) 场使用型号为 \(h_i\) 的车子,则第 \(j\) 场游戏要使用型号为 \(h_j\) 的车子。

你能帮小 L 选择每场游戏使用的赛车吗?如果有多种方案,输出任意一种方案。如果无解,输出 \(-1\) 。

\(1 \leq n \leq 50000, 0 \leq d \leq 8\)

解题思路 :

考虑没有 \(x\) 存在的情况所有地图只有两种可以选择的车辆,而限制条件是诸如选了 \(A\) 就要选 \(B\) 这种,不难发现是一个 \(2-sat\) 问题

设 \(A\) 表示 \(A\) 地图能用的第一辆车,\(A'\) 表示 \(A\) 地图能用的第二辆车

如果 \(A\) 选了就必须要选 \(B\) 的话,那么显然有 \(A’\) 选了就必须要选 \(B'\) 其他情况同理,这里可以直接连一条边

此外考虑一些特殊情况,如果选了 \(A\) 就必须选 \(B\) 但是 \(B\) 不能选的话,显然 \(A\) 也不能选,于是直接连一条 \(A\rightarrow A'\) 把选 \(A\) 的可能性否决掉

如果给出的限制\(A\) 不能选的话,可以直接无视掉这条限制,因为 \(A\) 本身就不在进行 \(Tarjan\) 的点中

至此我们就已经解决了没有 \(x\) 的情况,考虑有 \(x\) 怎么做

观察到 \(d\) 很小,可以暴力枚举 \(x\) 对应的地图是 \(a\) 还是 \(b\) 还是 \(c\) ,这样复杂度是 \(O(3^d(n+m))\) ,有可能会超时

但实际上当枚举到 \(x = a\) 和 \(x = b\) 的情况时,就已经枚举到了 \(x\) 选的车的所有情况 \((A,C) \cup (B,C)=(A,B,C)\)

所以可以直接枚举 \(x =a\) 或者 \(b\) 总复杂度 \(O(2^d(n+m))\)

/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int f = 0, ch = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
} #define Rint register int
const int N = 150005; char s[N];
vector<int> g[N];
int dfn[N], low[N], f[25], st[N], ins[N], ban[N], bel[N], Index, top, id;
int A[N], B[N], m1[N], m2[N], c1[N], c2[N], ans[N], n, m, d, cnt; inline void tarjan(int u){
dfn[u] = low[u] = ++Index, st[++top] = u, ins[u] = 1;
for(Rint i = 0; i < g[u].size(); i++){
int v = g[u][i];
if(!dfn[v]) tarjan(v), low[u] = Min(low[u], low[v]);
else if(ins[v]) low[u] = Min(low[u], dfn[v]);
}
if(dfn[u] == low[u]){
++id;
while(st[top] != u) ins[st[top]] = 0, bel[st[top--]] = id;
ins[st[top]] = 0, bel[st[top--]] = id;
}
}
inline int check(){
memset(dfn, 0, sizeof(dfn)), id = 0, Index = 0;
for(Rint i = 1; i <= 3 * n; i++) g[i].clear();
for(Rint i = 1; i <= m; i++){
if(A[m1[i]] != c1[i] && B[m1[i]] != c1[i]) continue;
int o1 = A[m1[i]] != c1[i] ? A[m1[i]] : B[m1[i]];
int o2 = A[m2[i]] != c2[i] ? A[m2[i]] : B[m2[i]];
if(A[m2[i]] != c2[i] && B[m2[i]] != c2[i]){
g[m1[i]+c1[i]].push_back(m1[i] + o1);
continue;
}
if(m1[i] == m2[i]){
if(c1[i] == c2[i]) continue;
g[m1[i]+c1[i]].push_back(m2[i]+c2[i]);
continue;
}
g[m2[i]+o2].push_back(m1[i] + o1);
g[m1[i]+c1[i]].push_back(m2[i] + c2[i]);
}
for(Rint i = 1; i <= 3 * n; i++) if(!dfn[i]) tarjan(i);
for(Rint i = 1; i <= n; i++){
if(bel[i+A[i]] == bel[i+B[i]]) return 0;
ans[i] = bel[i+A[i]] < bel[i+B[i]] ? A[i] : B[i];
}
for(Rint i = 1; i <= n; i++){
if(ans[i] == 0) putchar('A');
if(ans[i] == n) putchar('B');
if(ans[i] == 2 * n) putchar('C');
}
exit(0);
}
inline void dfs(int x){
if(x == cnt + 1) return (void) (check());
A[f[x]] = 0, B[f[x]] = n, dfs(x + 1);
A[f[x]] = 0, B[f[x]] = 2 * n, dfs(x + 1);
}
int main(){
read(n), read(d), scanf("%s", s + 1), read(m);
for(Rint i = 1; i <= m; i++){
read(m1[i]), c1[i] = getchar(), read(m2[i]), c2[i] = getchar();
c1[i] = (c1[i] - 'A') * n, c2[i] = (c2[i] - 'A') * n;
}
for(Rint i = 1; i <= n; i++) if(s[i] == 'x') f[++cnt] = i;
else{
if(s[i] == 'c') A[i] = 0, B[i] = n;
if(s[i] == 'b') A[i] = 0, B[i] = 2 * n;
if(s[i] == 'a') A[i] = n, B[i] = 2 * n;
}
dfs(1), cout << -1 << endl;
return 0;
}

「NOI2017」游戏的更多相关文章

  1. LOJ_2305_「NOI2017」游戏 _2-sat

    LOJ_2305_「NOI2017」游戏 _2-sat 题意: 给你一个长度为n的字符串S,其中第i个字符为a表示第i个地图只能用B,C两种赛车,为b表示第i个地图只能用A,C两种赛车,为c表示第i个 ...

  2. loj #2305. 「NOI2017」游戏

    #2305. 「NOI2017」游戏 题目描述 小 L 计划进行 nnn 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 AAA.BBB. ...

  3. LOJ2305 「NOI2017」游戏

    「NOI2017」游戏 题目背景 狂野飙车是小 L 最喜欢的游戏.与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略. 题目描述 小 L 计划进行$n$场 ...

  4. 「NOI2017」游戏 解题报告

    「NOI2017」游戏 \(d\)这么小,你考虑直接对\(d\)个东西暴力 枚举\(x\)为\(a\)或\(b\)(\(c\)就不用了,因为\(a,b\)已经包含\(c\))了,剩下的就是个\(2-s ...

  5. loj#2305. 「NOI2017」游戏 2-sat

    链接 https://loj.ac/problem/2305 https://www.luogu.org/problemnew/show/P3825 思路 3-sat神马的就不要想了,NP问题 除去x ...

  6. 【LOJ】 #2305. 「NOI2017」游戏

    题解 枚举x所在的地图的颜色,然后2-SAT建边 如果v所在的地图刚好是不能选的,那么u这边只能选另一种颜色 否则就是u的颜色到v的颜色 v的另一种颜色到u的另一种颜色 代码 #include < ...

  7. LG3825/BZOJ4945/LOJ2305 「NOI2017」游戏 dfs+2-SAT

    问题描述 LG3825 BZOJ4945 LOJ2305 题解 发现对于每个地图,如果没有\(A,B,C\)地图不可以使用\(a,b,c\),就是一个\(\mathrm{3-SAT}\)问题. 有了这 ...

  8. 「HNOI2018」游戏

    「HNOI2018」游戏 解题思路 首先没有锁上的门可以缩点缩掉,然后对于一扇锁上的门,如果钥匙在左边,那么右边就永远不可能到达左边,同理如果钥匙在右边,左边就永远不可能到达右边. 然后考虑一个暴力的 ...

  9. LOJ2303 「NOI2017」蚯蚓排队

    「NOI2017」蚯蚓排队 题目描述 蚯蚓幼儿园有$n$只蚯蚓.幼儿园园长神刀手为了管理方便,时常让这些蚯蚓们列队表演. 所有蚯蚓用从$1$到$n$的连续正整数编号.每只蚯蚓的长度可以用一个正整数表示 ...

随机推荐

  1. [linux]linux下安装mysql

    1.安装g++$sudo apt-get install build-essential注:此命令会同时安装gcc和make2.安装cmake$sudo apt-get install cmake3. ...

  2. 浮动&定位

    本文地址:http://www.cnblogs.com/veinyin/p/7606652.html  浮动和定位能够让我们把一些元素放到理想的位置,当然,相比之下 float 只能浮动到左边或右边, ...

  3. Markdown tutorial [repost]

    1. italic We'll start by learning two basic elements in text formatting: italics and bold. In these ...

  4. 商城项目(ssm+dubbo+nginx+mysql统合项目)总结(2)

    我不会在这里贴代码和详细步骤什么的,我觉得就算我把它贴出来,你们照着步骤做还是会出很多问题,我推荐你们去看一下黑马的这个视频,我个人感觉很不错,一步一步走下来可以学到很多东西.另外,视频和相关文档的话 ...

  5. Linux内存高,触发oom-killer问题解决

    最近遇到两起Linux的内存问题,其一是触发了oom-killer导致系统挂 1. 首先确认该系统的版本是32位 ? #uname -a Linux alarm 2.6.9-67.ELsmp #1 S ...

  6. ProxySQL 监控和统计

    ProxySQL 监控和统计 很多有价值的统计数据在stats和monitor库中. admin@127.0.0.1 [(none)]>SHOW TABLES FROM stats; +---- ...

  7. caffe Python API 之Accuracy

    net.acc = caffe.layers.Accuracy(net.fc3,net.label) 输出: layer { name: "acc" type: "Acc ...

  8. Ubuntu 下查看已安装的软件

    Ubuntu 下如何查看已安装的软件 1.查看安装的所有软件 dpkg -l 例如: dpkg -l | grep ftp 2.查看软件安装的路径 dpkg -L | grep ftp 也可以用 wh ...

  9. hashCode()与equals()区别

    这两个方法均是超类Object自带的成员方法.Object类是所有Java类的祖先.每个类都使用 Object 作为超类.所有对象(包括数组)都实现这个类的方法.在不明确给出超类的情况下,Java会自 ...

  10. Jinja2 及 render_template 的深度用法

    是时候开始写个前端了,Flask中默认的模板语言是Jinja2 现在我们来一步一步的学习一下 Jinja2 捎带手把 render_template 中留下的疑问解决一下 首先我们要在后端定义几个字符 ...