「NOI2017」游戏
「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」游戏的更多相关文章
- LOJ_2305_「NOI2017」游戏 _2-sat
LOJ_2305_「NOI2017」游戏 _2-sat 题意: 给你一个长度为n的字符串S,其中第i个字符为a表示第i个地图只能用B,C两种赛车,为b表示第i个地图只能用A,C两种赛车,为c表示第i个 ...
- loj #2305. 「NOI2017」游戏
#2305. 「NOI2017」游戏 题目描述 小 L 计划进行 nnn 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 AAA.BBB. ...
- LOJ2305 「NOI2017」游戏
「NOI2017」游戏 题目背景 狂野飙车是小 L 最喜欢的游戏.与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略. 题目描述 小 L 计划进行$n$场 ...
- 「NOI2017」游戏 解题报告
「NOI2017」游戏 \(d\)这么小,你考虑直接对\(d\)个东西暴力 枚举\(x\)为\(a\)或\(b\)(\(c\)就不用了,因为\(a,b\)已经包含\(c\))了,剩下的就是个\(2-s ...
- loj#2305. 「NOI2017」游戏 2-sat
链接 https://loj.ac/problem/2305 https://www.luogu.org/problemnew/show/P3825 思路 3-sat神马的就不要想了,NP问题 除去x ...
- 【LOJ】 #2305. 「NOI2017」游戏
题解 枚举x所在的地图的颜色,然后2-SAT建边 如果v所在的地图刚好是不能选的,那么u这边只能选另一种颜色 否则就是u的颜色到v的颜色 v的另一种颜色到u的另一种颜色 代码 #include < ...
- LG3825/BZOJ4945/LOJ2305 「NOI2017」游戏 dfs+2-SAT
问题描述 LG3825 BZOJ4945 LOJ2305 题解 发现对于每个地图,如果没有\(A,B,C\)地图不可以使用\(a,b,c\),就是一个\(\mathrm{3-SAT}\)问题. 有了这 ...
- 「HNOI2018」游戏
「HNOI2018」游戏 解题思路 首先没有锁上的门可以缩点缩掉,然后对于一扇锁上的门,如果钥匙在左边,那么右边就永远不可能到达左边,同理如果钥匙在右边,左边就永远不可能到达右边. 然后考虑一个暴力的 ...
- LOJ2303 「NOI2017」蚯蚓排队
「NOI2017」蚯蚓排队 题目描述 蚯蚓幼儿园有$n$只蚯蚓.幼儿园园长神刀手为了管理方便,时常让这些蚯蚓们列队表演. 所有蚯蚓用从$1$到$n$的连续正整数编号.每只蚯蚓的长度可以用一个正整数表示 ...
随机推荐
- 【CodeForces】704 C. Black Widow 动态规划+模拟
[题目]C. Black Widow [题意]给定一个表达式,形式为(...)^(...)^......^(...)=1(n个括号),括号中为1~2个值取或.有m个变量,给出表达式的值为xi或 !xi ...
- 2017ACM暑期多校联合训练 - Team 6 1010 HDU 6105 Gameia (博弈)
题目链接 Problem Description Alice and Bob are playing a game called 'Gameia ? Gameia !'. The game goes ...
- vscode中go插件配置
# 转自:http://www.mamicode.com/info-detail-2436665.html # https://blog.csdn.net/bing2011/article/detai ...
- python常用运维脚本实例【转】
file是一个类,使用file('file_name', 'r+')这种方式打开文件,返回一个file对象,以写模式打开文件不存在则会被创建.但是更推荐使用内置函数open()来打开一个文件 . 首先 ...
- 010 JVM类加载
转自http://www.importnew.com/23742.html 前言 我们知道我们写的程序经过编译后成为了.class文件,.class文件中描述了类的各种信息,最终都需要加载到虚拟机之后 ...
- PostGIS 操作geometry方法
WKT定义几何对象格式: POINT(0 0) ——点 LINESTRING(0 0,1 1,1 2) ——线 POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2 ...
- js中startWith、endWith 函数不能在任何浏览器兼容的问题
在做js测试的时候用到了startsWith函数,但是他并不是每个浏览器都有的,所以我们一般要重写一下这个函数,具体的用法可以稍微总结一下 在有些浏览器中他是undefined 所以我们可以这样的处理 ...
- 关于OnPaint、FormPaint会不停的触发 触发多次的情形---讨论总结
关于OnPaint会不停的一直触发 触发多次的问题,是这样的 首先OnPaint是响应windows的WM_PAINT消息的,你显示器上 能看到的比如说 按钮button, memo什么的 都是画出来 ...
- Codefroces 919D Substring(拓扑排序+DP)
题目链接:http://codeforces.com/problemset/problem/919/D 题目大意:给你一张有向图,给你每个顶点上的字母和一些边,让你找出一条路径,路径上的相同字母数最多 ...
- span文字里面自动换行时怎么办
可以用white-space:nowrap来强制文字不换行,知道遇到<br>为止