[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 ...
随机推荐
- 移动APP用例设计中的关键点(转载)
http://www.51testing.com/html/52/n-4421752.html 在测试工作中我们需要不断的总结和储备自己的知识和经验,譬如具备特定属性.环境以及场景,如:PC,手机,智 ...
- SQL之CASE WHEN用法详解[1]
简单CASE WHEN函数: CASE SCORE WHEN 'A' THEN '优' ELSE '不及格' END CASE SCORE WHEN 'B' THEN '良' ELSE '不及格' E ...
- oss命令使用
下载文件夹 ossutil64 cp oss://folder/ out_folder/ -r --jobs 20
- JQuery operate xml
msg is <?xml ?> <Parameters> <WorkflowName>...</WorkflowName> </Parameter ...
- Nginx geo模块
geo 模块默认编译进nginx 可以通过--without-http_geo_module禁用 Syntax: geo [$address] $variable { ... } Default: — ...
- JarvisOJ Basic easyRSA
还记得veryeasy RSA吗?是不是不难?那继续来看看这题吧,这题也不难. 已知一段RSA加密的信息为:0xdc2eeeb2782c且已知加密所用的公钥: (N=322831561921859 e ...
- ftell 的使用
ftell一般用于读取文件的长度,下面补充一个例子,读取文本文件中的内容: #include <stdio.h> #include <stdlib.h> int main() ...
- linux中安装gcc
在使用CentOS的yum -y install 时 可以先进入 /etc/yum.repos.d/ 文件下,将CentOS-Base.repo文件名改为CentOS-Base.repo.bak使 ...
- BZOJ3724PA2014Final Krolestwo——欧拉回路+构造
题目描述 你有一个无向连通图,边的总数为偶数.设图中有k个奇点(度数为奇数的点),你需要把它们配成k/2个点对(显然k被2整除).对于每个点对(u,v),你需要用一条长度为偶数(假设每条边长度为1)的 ...
- windows 系统错误码总结
windows 错误码大全: 操作成功完成. 功能错误. 系统找不到指定的文件. 系统找不到指定的路径. 系统无法打开文件. 拒绝访问. 句柄无效. 存储控制块被损坏. 存储空间不足,无法处理此命令. ...