题目背景

狂野飙车是小 L 最喜欢的游戏。与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略。

题目描述

小 L 计划进行nn 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏。

小 L 的赛车有三辆,分别用大写字母ABC表示。地图一共有四种,分别用小写字母xabc表示。其中,赛车A不适合在地图a上使用,赛车B不适合在地图b上使用,赛车C不适合在地图c上使用,而地图x则适合所有赛车参加。适合所有赛车参加的地图并不多见,最多只会有d张。

nn 场游戏的地图可以用一个小写字母组成的字符串描述。例如:S=xaabxcbc表示小 L 计划进行88 场游戏,其中第11 场和第55 场的地图类型是x,适合所有赛车,第22 场和第33 场的地图是a,不适合赛车A,第44 场和第77 场的地图是b,不适合赛车B,第66 场和第88 场的地图是c,不适合赛车C

小 L 对游戏有一些特殊的要求,这些要求可以用四元组 (i, h_i, j, h_j)(i,hi​,j,hj​) 来描述,表示若在第ii 场使用型号为h_ihi​ 的车子,则第jj场游戏要使用型号为h_jhj​ 的车子。

你能帮小 L 选择每场游戏使用的赛车吗?如果有多种方案,输出任意一种方案。如果无解,输出 “-1’’(不含双引号)。

输入输出格式

输入格式:

输入第一行包含两个非负整数n, dn,d 。

输入第二行为一个字符串SS 。n, d, Sn,d,S 的含义见题目描述,其中SS 包含nn 个字符,且其中恰好dd 个为小写字母xx 。

输入第三行为一个正整数mm ,表示有mm 条用车规则。接下来mm 行,每行包含一个四元组i, h_i, j, h_ji,hi​,j,hj​ ,其中i, ji,j 为整数,h_i, h_jhi​,hj​ 为字符abc,含义见题目描述。

输出格式:

输出一行。

若无解输出 “-1’’(不含双引号)。

若有解,则包含一个长度为nn 的仅包含大写字母ABC的字符串,表示小 L 在这nn 场游戏中如何安排赛车的使用。如果存在多组解,输出其中任意一组即可。

题意:

     有n个场地,三个赛车,每个场地适合某两种三种赛车,再给出m个限制条件,形式为A x B y 即A使用x,B必须使用y;

题解:

aaarticlea/png;base64,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" alt="" />

    ①2-SAT

    如果每张图只能选两个车,具体的对于每一个条件,连如图的有向边:意思就是如果A号场地用了x车,B号场地一定用了y车,反之,如果B号场地不用y车,那么A号场地一定不是x车。可以发现这个图的对称性。

    对这个图跑缩点,在一个强联通里的所有点表示逻辑上可以互相推理,同一个场地A的x和y不能同时被选。枚举A,如果A的两个选择在一个联通里,则无法构造出方案,否则可以;

    ②输出方案:随便从一个A开始,任意选择一个联通,选择联通里的所有A,并将联通里所有的选择的另一种选择所在联通和这些联通的前驱联通都删掉,最后可以构造出解;这样子本来是要反向拓扑排序,但是由于tarjan算法做完之后已经是反拓扑序,所以就不需要再写一遍;

     ③因为题中三种车都可以跑的图的个数d很小,那么对于每一个这样的图枚举两种情况就可以表达三种车了;

    

#include<bits/stdc++.h>
using namespace std;
const int N = ,da = 'a' - ,dA = 'A' - ;
int n,m,d,s[N],idx[N][],typ[N],dfn[N],low[N],bl[N],tot,st[N],top,cnt,hd[N],o,preo,prehd[N],del[N],ans[N];
struct data{int x1,c1,x2,c2;};
vector<int>X,son[N],fm[N]; vector<data>Q;
struct Edge{int v,nt;}E[N];
char gc(){
static char *p1,*p2,s[];
if(p1==p2) p2=(p1=s)+fread(s,,,stdin);
return(p1==p2)?EOF:*p1++;
}
int rd(){
int x = ; char c = gc();
while(c<''||c>'') c = gc();
while(c>=''&&c<='') x = x * + c - '',c = gc();
return x;
}
char gt(){
char c = gc();
while(!isalpha(c)) c = gc();
return c;
}
void adde(int u,int v){E[o] = (Edge){v,hd[u]}; hd[u] = o++;}
void init(int x1,int c1,int x2,int c2){
if(!s[x1]||!s[x2]){
Q.push_back((data){x1,c1,x2,c2});
return ;
}
if(s[x1]==c1) return ;
if(s[x2]==c2) {adde(idx[x1][c1],idx[x1][ - s[x1] - c1]);return ;}
adde(idx[x1][c1],idx[x2][c2]);
adde(idx[x2][ - s[x2] - c2],idx[x1][ - s[x1] - c1]);
}
void tarjan(int u){
dfn[u] = low[u] = ++tot; st[++top] = u;
for(int i = hd[u],v;i!=-;i=E[i].nt){
if(!dfn[v=E[i].v]) tarjan(v),low[u]=min(low[u],low[v]);
else if(!bl[v]) low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
cnt++;
do bl[st[top]]=cnt;
while(st[top--]!=u);
}
}
bool sat(){
top = tot = cnt = ;
for(int i = ;i <= *n+;i++) dfn[i] = low[i] = bl[i] = del[i] = ;
for(int i = ;i <= *n+;i++) if(!dfn[i]) tarjan(i);
for(int i = ;i <= *n+;i+=) if(bl[i]==bl[i^]) return false;
return true;
}
void clear(int i){
if(del[i])return; del[i] = ;
for(int j = ;j < fm[i].size();j++) clear(fm[i][j]);
}
void update(int i){
clear(bl[i^]);
ans[i/] = typ[i];
}
void Print(){
for(int i = ;i <= *n+;i++) son[bl[i]].push_back(i);
for(int i = ;i <= *n+;i++)
for(int j = hd[i];j!=-;j=E[j].nt){
fm[bl[E[j].v]].push_back(bl[i]);
}
for(int i = ;i <= cnt;i++)if(!del[i])
for(int j = ;j < son[i].size();j++)
update(son[i][j]);
for(int i = ;i <= n;i++) putchar(ans[i]+dA); printf("\n");
}
int main()
{ freopen("mzoj1114.in","r",stdin);
freopen("mzoj1114.out","w",stdout);
n = rd();
d = rd();
for(int i = ;i <= n;i++) {
char c = gt();
if(c!='x') {
s[i] = c - da;
for(int j = ,k = *i;j <= ;j++) if(s[i]!=j) idx[i][j] = k,typ[k++] = j;
}else X.push_back(i);
}
m = rd();
memset(hd,-,sizeof(hd));
for(int i = ;i <= m;i++) {
int x1,x2; char c1,c2;
x1 = rd(); c1 = gt()-dA;
x2 = rd(); c2 = gt()-dA;
init(x1,c1,x2,c2);
}
preo = o; for(int i = ;i <= *n+;i++) prehd[i] = hd[i];
for(int i = ;i < (<<d);i++){
for(int j = ;j < d;j++){
int x = X[j];
if(i&(<<j)) s[x] = ,typ[idx[x][] = *x] = ,typ[idx[x][] = *x+] = ;
else s[x] = ,typ[idx[x][] = *x] = ,typ[idx[x][] = *x+] = ;
}
o = preo; for(int i1 = ;i1 <= *n+;i1++) hd[i1] = prehd[i1];
for(int j = ;j < Q.size();j++) init(Q[j].x1,Q[j].c1,Q[j].x2,Q[j].c2);
if(sat()) Print(),exit();
// for(int j = 0;j < n;j++) s[X[i]] = 0;
}
puts("-1");
return ;
}//by tkys_Austin;


     

bzoj3825 NOI2017 游戏的更多相关文章

  1. P3825 [NOI2017]游戏

    题目 P3825 [NOI2017]游戏 做法 \(x\)地图外的地图好做,模型:\((x,y)\)必须同时选\(x \rightarrow y,y^\prime \rightarrow x^\pri ...

  2. 【BZOJ4945】[Noi2017]游戏 2-SAT

    [BZOJ4945][Noi2017]游戏 题目描述 题解:2-SAT学艺不精啊! 这题一打眼看上去是个3-SAT?哎?3-SAT不是NPC吗?哎?这题x怎么只有8个?暴力走起! 因为x要么不是A要么 ...

  3. [Luogu P3825] [NOI2017] 游戏 (2-SAT)

    [Luogu P3825] [NOI2017] 游戏 (2-SAT) 题面 题面较长,略 分析 看到这些约束,应该想到这是类似2-SAT的问题.但是x地图很麻烦,因为k-SAT问题在k>2的时候 ...

  4. [NOI2017]游戏(2-SAT)

    这是约半年前写的题解了,就搬过来吧 感觉这是NOI2017最水的一题(当然我还是不会2333),因为是一道裸的2-SAT.我就是看着这道题学的2-SAT 算法一:暴力枚举.对于abc二进制枚举,对于x ...

  5. NOI2017 [NOI2017]游戏 【2-sat】

    题目 题目背景 狂野飙车是小 L 最喜欢的游戏.与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略. 题目描述 小 L 计划进行nn 场游戏,每场游戏使用 ...

  6. bzoj 4945: [Noi2017]游戏

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

  7. [NOI2017]游戏

    题目描述 http://www.lydsy.com/JudgeOnline/upload/Noi2017D2.pdf 题解 如果说没有x的话,那么每一局只能有两种选择,可以描述为是/非,每条限制也可以 ...

  8. 洛谷3825 [NOI2017]游戏 2-sat

    原文链接http://www.cnblogs.com/zhouzhendong/p/8146041.html 题目传送门 - 洛谷3825 题解 我们考虑到地图中x的个数很少,最多只有8个. 所以我们 ...

  9. Luogu3825 NOI2017 游戏 2-SAT

    传送门 第一眼看上去似乎是一个3-SAT问题 然而\(d \leq 8\)给我们的信息就是:暴力枚举 枚举\(x\)型地图变成\(a\)型地图还是\(b\)型地图(实际上不要枚举\(c\),因为\(a ...

随机推荐

  1. python day1 基本语法作业

    一.过7 start =1 while start<=10: if start !=7: print(start) start +=1 二.100以内的和 sum = 0 start = 1 w ...

  2. Flask 学习 六 大型程序结构

    pip freeze >requirement.txt 自动生成版本号 pip install -r requirement.txt 自动下载对应的库 梳理结构 config.py #!/usr ...

  3. 关于安装win7系统时出现0x0000007b电脑蓝屏代码的问题

    问题解析: 0X0000007B 这个错误网上都说是sata硬盘的什么引导模式的原因引起. 在网上查找了很久,大概引起错误的原因就是:sata和ide两种模式不同,前者可以装win7系统,后者是xp系 ...

  4. sql 多条记录插入

    --多条记录插入,用逗号分开值. INSERT dbo.studentinfor ( id, name, class, age, hpsw ) ', -- id - nvarchar(50) N'te ...

  5. Crontab定时备份数据库

    1.创建一个shell脚本文件 cd /usr mkdir dbbackup cd /usr/dbbackup vim backup.sh echo "------------------- ...

  6. Leetcode:Two Sum

    原题:https://leetcode.com/problems/two-sum/ 尝试了两种方法: 方法一: var twoSum = function(nums, target) { for(va ...

  7. Angular 学习笔记 ( CDK - Observers )

    <div class="projected-content-wrapper" (cdkObserveContent)="projectContentChanged( ...

  8. api-gateway实践(03)新服务网关 - 网关请求拦截检查

    参考链接:http://www.cnblogs.com/jivi/archive/2013/03/10/2952829.html 一.为什么要拦截检查请求? 防止重放攻击.篡改重放,进行使用规格检查 ...

  9. leetcode算法:Two Sum II - Input array is sorted

    Given an array of integers that is already sorted in ascending order, find two numbers such that the ...

  10. Lintcode373 Partition Array by Odd and Even solution 题解

    [题目描述] Partition an integers array into odd number first and even number second. 分割一个整数数组,使得奇数在前偶数在后 ...