[NOI2017]游戏(2-SAT)
这是约半年前写的题解了,就搬过来吧
感觉这是NOI2017最水的一题(当然我还是不会2333),因为是一道裸的2-SAT。我就是看着这道题学的2-SAT
算法一:暴力枚举。对于abc二进制枚举,对于x则采用三进制枚举即可,复杂度O(3^d*2^(n-d)),再进行适当剪支,期望得分:40~50
算法二:对于d=0的点,采用2-SAT算法,这是最裸的2-SAT,这样,复杂度为O(n+m),综合算法一,期望得分为60
算法三:不妨对于d个x,采用三进制枚举,枚举a/b/c,再做裸的2-SAT即可,复杂度O(3^d*(n+m)),期望得分:75~90,如果常数小可以X过去
算法四:不难发现,三进制枚举不但效率慢,而且难写、没必要,对于判断会很复杂,不如只枚举禁止使用A/B,因为这样已经包含了A/B/C三种赛车,所以可以这么做(因为题目只要求一组解),复杂度O(2^d*(n+m)),期望得分:100
难点:2-SAT和输出方案的2-SAT
注意:选A就选B等价于选B'就选A’,所以需要连接双向边!!
不说了上code
#include<bits/stdc++.h>
#define mem(x) memset(x,0,sizeof x)
using namespace std;
const int N=2e5+;
int n,m,d,scc,cnt,top,c[N],s1[N],t1[N],dfn[N],low[N],part[N],hd[N],v[N],nxt[N],q[N];
char s[N],s2[N],t2[N],t[N];
bool vis[N],flag;
void add(int x,int y){v[++cnt]=y;nxt[cnt]=hd[x];hd[x]=cnt;}
int opp(int x){return x>n?x-n:x+n;}
int jisuan(int x,char ch)
{
if(s[x]=='a')return ch=='B'?x:x+n;
if(s[x]=='b'||s[x]=='c')return ch=='A'?x:x+n;
if(ch=='C')return x+n;
return x;
}
void tarjan(int u)
{
dfn[u]=low[u]=++cnt;
q[++top]=u;
vis[u]=;
for(int i=hd[u];i;i=nxt[i])
if(!dfn[v[i]])
{
tarjan(v[i]);
low[u]=min(low[u],low[v[i]]);
}
else if(vis[v[i]])low[u]=min(low[u],dfn[v[i]]);
if(dfn[u]==low[u])
{
part[u]=++scc;
vis[u]=;
int now;
do{
now=q[top--];
vis[now]=;
part[now]=scc;
}while(now!=u);
}
}
void solve()
{
scc=cnt=;
mem(dfn);mem(low);mem(part);mem(hd);mem(nxt);
for(int i=;i<=m;i++)
if(s[s1[i]]!='x'&&s[t1[i]]!='x'&&s[s1[i]]-!=s2[i])
{
int u=jisuan(s1[i],s2[i]),v;
if(s[t1[i]]-==t2[i])add(u,opp(u));
else{
v=jisuan(t1[i],t2[i]);
add(u,v);add(opp(v),opp(u));
}
}
else{
char S=s[s1[i]],T=s[t1[i]];
int x=c[s1[i]],y=c[t1[i]];
if(S=='x'&&T=='x'&&s2[i]!=t[x])
{
int u=jisuan(s1[i],s2[i]),v;
if(t2[i]==t[y])add(u,opp(u));
else{
v=jisuan(t1[i],t2[i]);
add(u,v);add(opp(v),opp(u));
}
}
else if(S=='x'&&T!='x'&&s2[i]!=t[x])
{
int u=jisuan(s1[i],s2[i]),v;
if(s[t1[i]]-==t2[i])add(u,opp(u));
else{
v=jisuan(t1[i],t2[i]);
add(u,v);add(opp(v),opp(u));
}
}
else if(S!='x'&&T=='x'&&s[s1[i]]-!=s2[i])
{
int u=jisuan(s1[i],s2[i]),v;
if(t2[i]==t[y])add(u,opp(u));
else{
v=jisuan(t1[i],t2[i]);
add(u,v);add(opp(v),opp(u));
}
}
}
cnt=;
for(int i=;i<=n*;i++)if(!dfn[i])tarjan(i);
for(int i=;i<=n;i++)if(part[i]==part[i+n])return;
for(int i=;i<=n;i++)
if(part[i]<part[i+n])
{
if(s[i]=='a')printf("B");
else if(s[i]=='b'||s[i]=='c')printf("A");
else if(t[c[i]]=='A')printf("B");
else printf("A");
}
else{
if(s[i]=='a'||s[i]=='b')printf("C");
else if(s[i]=='c')printf("B");
else if(t[c[i]]=='A')printf("C");
else printf("B");
}
flag=;
}
void fact(int k)
{
if(flag)return;
if(k>d){solve();return;}
t[k]='A';fact(k+);t[k]='B';fact(k+);
}
int main()
{
scanf("%d%d",&n,&d);
d=;
scanf("%s",s+);
for(int i=;i<=n;i++)if(s[i]=='x')c[i]=++d;
scanf("%d",&m);
for(int i=;i<=m;i++)scanf("%d %c%d %c",&s1[i],&s2[i],&t1[i],&t2[i]);
fact();
if(!flag)puts("-1");
}
[NOI2017]游戏(2-SAT)的更多相关文章
- P3825 [NOI2017]游戏
题目 P3825 [NOI2017]游戏 做法 \(x\)地图外的地图好做,模型:\((x,y)\)必须同时选\(x \rightarrow y,y^\prime \rightarrow x^\pri ...
- 【BZOJ4945】[Noi2017]游戏 2-SAT
[BZOJ4945][Noi2017]游戏 题目描述 题解:2-SAT学艺不精啊! 这题一打眼看上去是个3-SAT?哎?3-SAT不是NPC吗?哎?这题x怎么只有8个?暴力走起! 因为x要么不是A要么 ...
- [Luogu P3825] [NOI2017] 游戏 (2-SAT)
[Luogu P3825] [NOI2017] 游戏 (2-SAT) 题面 题面较长,略 分析 看到这些约束,应该想到这是类似2-SAT的问题.但是x地图很麻烦,因为k-SAT问题在k>2的时候 ...
- bzoj3825 NOI2017 游戏
题目背景 狂野飙车是小 L 最喜欢的游戏.与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略. 题目描述 小 L 计划进行nn 场游戏,每场游戏使用一张地 ...
- NOI2017 [NOI2017]游戏 【2-sat】
题目 题目背景 狂野飙车是小 L 最喜欢的游戏.与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略. 题目描述 小 L 计划进行nn 场游戏,每场游戏使用 ...
- bzoj 4945: [Noi2017]游戏
Description Solution 首先我们发现一个位置如果不是 \('x'\),那么就只有两种选择 而 \('x'\) 的个数小于等于 \(8\),直接枚举是哪个就好了 然后就是 \(2-sa ...
- [NOI2017]游戏
题目描述 http://www.lydsy.com/JudgeOnline/upload/Noi2017D2.pdf 题解 如果说没有x的话,那么每一局只能有两种选择,可以描述为是/非,每条限制也可以 ...
- 洛谷3825 [NOI2017]游戏 2-sat
原文链接http://www.cnblogs.com/zhouzhendong/p/8146041.html 题目传送门 - 洛谷3825 题解 我们考虑到地图中x的个数很少,最多只有8个. 所以我们 ...
- Luogu3825 NOI2017 游戏 2-SAT
传送门 第一眼看上去似乎是一个3-SAT问题 然而\(d \leq 8\)给我们的信息就是:暴力枚举 枚举\(x\)型地图变成\(a\)型地图还是\(b\)型地图(实际上不要枚举\(c\),因为\(a ...
随机推荐
- python之路--管道, 事件, 信号量, 进程池
一 . 管道 (了解) from multiprocessing import Process, Pipe def f1(conn): # 管道的recv 里面不用写数字 from_main_proc ...
- Golang的select多路复用以及channel使用实践
看到有个例子实现了一个类似于核弹发射装置,在发射之前还是需要随时能输入终止发射. 这里就可以用到cahnnel 配合select 实现多路复用. select的写法用法有点像switch.但是和swi ...
- django migrate报错(提前删除表等)
python3 manage.py makemigrations python3 manage.py migrate ##报错 改为##更改migrates的状态 python3 manage.py ...
- debug方法
debug as -> spring boot->开始了 可以添加 ,, 来进行向下步骤:使用其他方法(在方法内打点) 一步步F6就可以了
- php1
正则表达式 $p = '/name:(\w+\s?\w+)/'; $str = "name:steven jobs"; preg_match($p, $str, $match); ...
- codeforces347B
Fixed Points CodeForces - 347B A permutation of length n is an integer sequence such that each integ ...
- 11/5/2018模拟 Problem C
题面 题解 我有特殊的哈希技巧 以到下一个相同字符的距离为值哈希, 如果不存在或在串外, 就是 \(|T| + 1\). 加入一个新字符 \(S_i\) 时, 同时修改它上一次出现时的值, 由 \(| ...
- ubuntu系统备份与恢复-remastersys方法
http://blog.csdn.net/yaoqi_isee/article/details/73730010 http://blog.csdn.net/handsome_sheng/article ...
- Linux编译静态库与共享库
静态库: cc -c mod1.c mod2.c //编译 ar r libdemo.a mod1.o mod2.o //生成静态库 cc -c prog.c //编 ...
- Lisp小程序,大作用,不该放弃!
从听说autolisp到现在已经20年了, 学了一点点, 可惜中间没能坚持下来, 放弃了! 今天在画图, 图纸是从revit转成dwg的, 其中有些文本的朝向是错误的, 如果手工旋转很是费事, ...