这是约半年前写的题解了,就搬过来吧

感觉这是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+99;
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]=1;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]=0;int now;do{now=q[top--];vis[now]=0;part[now]=scc;}while(now!=u);}
}
void solve()
{scc=cnt=0;mem(dfn);mem(low);mem(part);mem(hd);mem(nxt);for(int i=1;i<=m;i++)if(s[s1[i]]!='x'&&s[t1[i]]!='x'&&s[s1[i]]-32!=s2[i]){int u=jisuan(s1[i],s2[i]),v;if(s[t1[i]]-32==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]]-32==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]]-32!=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=0;for(int i=1;i<=n*2;i++)if(!dfn[i])tarjan(i);for(int i=1;i<=n;i++)if(part[i]==part[i+n])return;for(int i=1;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=1;
}
void fact(int k)
{if(flag)return;if(k>d){solve();return;}t[k]='A';fact(k+1);t[k]='B';fact(k+1);
}
int main()
{scanf("%d%d",&n,&d);d=0;scanf("%s",s+1);for(int i=1;i<=n;i++)if(s[i]=='x')c[i]=++d;scanf("%d",&m);for(int i=1;i<=m;i++)scanf("%d %c%d %c",&s1[i],&s2[i],&t1[i],&t2[i]);fact(1);if(!flag)puts("-1");
}

View Code

转载于:https://www.cnblogs.com/hfctf0210/p/10155788.html

[NOI2017]游戏(2-SAT)相关推荐

  1. P3825 [NOI2017]游戏

    P3825 [NOI2017]游戏 题目描述 小 L 计划进行n场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母A.B.C表示.地图一共有四 ...

  2. bzoj 4945: [Noi2017]游戏

    Description Solution 首先我们发现一个位置如果不是 \('x'\),那么就只有两种选择 而 \('x'\) 的个数小于等于 \(8\),直接枚举是哪个就好了 然后就是 \(2-sa ...

  3. 暑假训练-义乌(7.8-7.15)

    暑假训练 模拟赛 图表 数据 7.8(lxl) 7.9(lxl) 7.10(lxl) 7.11(lxl) 7.12(wls) 7.13(wls) 7.14(wls) 7.15(lfds) 训练 数据结 ...

  4. Luogu P4782 【模板】2-SAT 问题(2-SAT)

    P4782 [模板]2-SAT 问题 题意 题目背景 \(2-SAT\)问题模板 题目描述 有\(n\)个布尔变量\(x_1\sim x_n\),另有\(m\)个需要满足的条件,每个条件的形式都是&q ...

  5. PKUSC2018训练日程(4.18~5.30)

    (总计:共66题) 4.18~4.25:19题 4.26~5.2:17题 5.3~5.9: 6题 5.10~5.16: 6题 5.17~5.23: 9题 5.24~5.30: 9题 4.18 [BZO ...

  6. 一句话题解(20170801~20170125)

    8.1 bzoj 4720 noip2016 换教室 floyd预处理+期望(薛定谔的猫) bzoj 4318 OSU! 三次函数期望值 从一次.二次推得 8.2 bzoj 1076 状压+期望DP ...

  7. NOI2010~NOI2018选做

    [NOI2010] [NOI2010]海拔 高度只需要0/1,所以一个合法方案就是一个割,平面图求最小割. [NOI2010]航空管制 反序拓扑排序,每次取出第一类限制最大的放置,这样做答案不会更劣. ...

  8. 2-SAT问题的一种解法(简明易懂)

    2-sat即2元约束问题 下面不加证明地描述一种较优的解法: 为每个需要被判定的量建立true.false两个节点,方便起见称它们为互斥节点. 将约束条件抽象为代表推导关系的有向边. tarjan缩点 ...

  9. loj #2305. 「NOI2017」游戏

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

最新文章

  1. 真没想到,Python还能实现5毛特效
  2. WritableComparable排序案例(全排序)
  3. MySQL分库分表环境下全局ID生成方案
  4. 随手记一次用C#正则表达式获取下拉菜单html标签select以及相关属性值
  5. 阿联酋是发达国家还是发展中国家
  6. Jmeter(一)-精简测试脚本
  7. android Q版本外部存储问题以及获取空间大小问题
  8. 使用Kotlin的Android CoordinatorLayout
  9. brave浏览器_据说只有这款浏览器,真正做到了保护隐私
  10. 【WP开发】JSON数据的读与写
  11. java 枚举嵌套枚举_java – 如何使用枚举与分组和分组层次/嵌套
  12. date和datetime长度设置多少_太原市玻璃温室大棚多少钱
  13. 原始对偶方法——转载
  14. 将文本格式转为kindle可用格式
  15. linux编译安卓源码,Ubuntu下编译Android源码
  16. python csv写文件,用Excel打开中文乱码解决
  17. 管理用计算机修理费属于什么会计科目,维修费是什么会计科目
  18. idea使用Protobuf插件
  19. 阿里巴巴“相信小的伟大”:用普世情怀传播小力量
  20. Java 后端开发面试总结:25 个技术专题(最全面试攻略)

热门文章

  1. 混色,半透明的设定,以及我们视角即屏幕处在-1层,-1层的物体是看不见的
  2. my java note ---- 绑定
  3. 苹果后门、微软垄断与Linux缺位
  4. Java凝视Annotation
  5. Deep Learning 9_深度学习UFLDL教程:linear decoder_exercise(斯坦福大学深度学习教程)...
  6. IOS-资源最小化之点九图片的使用
  7. 解决:请购买WinRAR许可,您注册还剩下40天(WinRAR老是弹出烦人的对话框)
  8. flex 表格勾选后 鼠标滚动会自动勾选_办公鼠里的BBA,罗技MX Anywhere 3鼠标开箱体验...
  9. php 内容自动生成word文档,php生成word文档的例子
  10. JAVA连接数据库使用的API是什么呢,如何使用JDBC API在Java中建立数据库连接?