「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. 关于Java泛型深入理解小总结

    1.何为泛型 首先泛型的本质便是类型参数化,通俗的说就是用一个变量来表示类型,这个类型可以是String,Integer等等不确定,表明可接受的类型,原理类似如下代码 int pattern; //声 ...

  2. Eng1—English daily notes

    English daily notes 2015年 4月 Phrases As a side note 作为附注,顺便说句题外话,和by the way意思相近,例句 As a side note, ...

  3. C.Fountains(Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2)+线段树+RMQ)

    题目链接:http://codeforces.com/contest/799/problem/C 题目: 题意: 给你n种喷泉的价格和漂亮值,这n种喷泉题目指定用钻石或现金支付(分别用D和C表示),C ...

  4. 机器学习-kNN-寻找最好的超参数

    一 .超参数和模型参数 超参数:在算法运行前需要决定的参数 模型参数:算法运行过程中学习的参数 - kNN算法没有模型参数- kNN算法中的k是典型的超参数 寻找好的超参数 领域知识 经验数值 实验搜 ...

  5. 使用vscode实现git同步

    用了git最方便的就是项目同步管理,回到家打开vscode只需要点击一下pull就能全部同步过来.是不是很方便....毕竟之前我都是拿u盘拷贝回家或者存到云盘再下载下来..   我这里之前用的是国内的 ...

  6. iphone6设置企业qq

    1.首先要确定foxmail的账户服务器信息,右上角-账户账户管理-服务器设置 2.iphone端:

  7. python基础===100盏灯的问题

    闪存里有人这样提问这样: 第一轮操作所有电灯,第二轮操作第2盏,第4盏开关,以此类推,第三轮改变编号为3的倍数的电灯,第3盏,第6盏,如果原来那盏灯是亮的,就熄灭它,如果原来是灭的,就点亮它,以此类推 ...

  8. 去除\ufeff的解决方法,python语言

    语言:python 编程工具:pycharm 硬件环境:win10 64位 读取文件过程中发现一个问题:已有记事本文件(非空),转码 UTF-8,复制到pycharm中,在开始位置打印结果会出现  \ ...

  9. Spring源码解读Spring IOC原理

    一.什么是Ioc/DI? IoC 容器:最主要是完成了完成对象的创建和依赖的管理注入等等. 先从我们自己设计这样一个视角来考虑: 所谓控制反转,就是把原先我们代码里面需要实现的对象创建.依赖的代码,反 ...

  10. openjudge-NOI 2.6-2718 移动路线

    题目链接:http://noi.openjudge.cn/ch0206/2718/ 题解: 递推,某一个点只能从其左边或者下边走过来 f[i][j]存储(i,j)这个点上的结果,即f[i][j]=f[ ...