1032. 游戏

题目链接

1032. 游戏

狂野飙车是小 L 最喜欢的游戏。

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

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

L 的赛车有三辆,分别用大写字母 ABC 表示。

地图一共有四种,分别用小写字母 xabc 表示。

其中,赛车 A 不适合在地图 a 上使用,赛车 B 不适合在地图 b 上使用,赛车 C 不适合在地图 c 上使用,而地图 x 则适合所有赛车参加。

适合所有赛车参加的地图并不多见,最多只会有 d 张。

n 场游戏的地图可以用一个小写字母组成的字符串描述。

例如:S=xaabxcbc 表示小 L 计划进行 8 场游戏,其中第 1 场和第 5 场的地图类型是 x,适合所有赛车,第 2 场和第 3 场的地图是 a,不适合赛车 A,第 4 场和第 7 场的地图是 b,不适合赛车 B, 第 6 场和第 8 场的地图是 c,不适合赛车 C

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

你能帮小 L 选择每场游戏使用的赛车吗?

如果有多种方案,输出任意一种方案。

如果无解,输出 “1”(不含双引号)。

输入格式

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

输入第二行为一个字符串 S

n,d,S 的含义见题目描述,其中 S 包含 n 个字符,且其中恰好 d 个为小写字母 x

输入第三行为一个正整数 m ,表示有 m 条用车规则。

接下来 m 行,每行包含一个四元组 i,hi,j,hj ,其中 i,j 为整数,hi,hj 为字符 ABC,含义见题目描述。

输出格式

输出一行。

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

若有解,则包含一个长度为 n 的仅包含大写字母 ABC 的字符串,表示小 L 在这 n 场游戏中如何安排赛车的使用。

如果存在多组解,输出其中任意一组即可。

数据范围

image

输入样例:

3 1 xcc 1 1 A 2 B

输出样例:

ABA

样例解释

L 计划进行 3 场游戏,其中第 1 场的地图类型是 x,适合所有赛车,第 2 场和第 3 场的地图是 c,不适合赛车 C

L 希望:若第 1 场游戏使用赛车 A,则第 2 场游戏使用赛车 B

那么为这 3 场游戏分别安排赛车 ABA 可以满足所有条件。

若依次为 3 场游戏安排赛车为 BBBBAA 时,也可以满足所有条件,也被视为正确答案。

但依次安排赛车为 AABABC 时,因为不能满足所有条件,所以不被视为正确答案。

解题思路

2-SAT

对于 a,其只能使用 AB,对于 b,其只能使用 ac,对于 c,其只能使用 AB,对于 x,其可以使用 ABC,显然这是一个 2-SAT 和 3-SAT 结合的问题,即如果不考虑 x 存在的情况(即只存在 2-SAT 的情况),对于若干个条件,即如果第 i 场使用 x,则第 j 场应该使用 y,如果第 i 场本身就不能使用 x,则显然该条件没用,可以忽略,否则如果第 j 场本身不能使用 y,则应该使条件不成立,即第 i 场不应该使用 x,否则如果第 j 场能使用 y 的话,则应该使第 i 场使用 x 这个命题表示的节点指向第 j 场使用 y 这个命题表示的节点,同时逆否命题也需要加入边,但是回到问题本身, 3-SAT 是一个 NPC 问题,但是由于 x 的个数不是很多,但如果暴力枚举所有 x 的值的话也不行,但可以将 3-SAT 问题转化为 2-SAT 问题,即对于有 x 的场次来说,其一定是选 BC,或者选 AC,即其可以等价于两种 2-SAT,共有 2d 种组合,这样就将问题完全转化为 2-SAT 问题

  • 时间复杂度:O(2d×(n+m)

代码

// Problem: 游戏 // Contest: AcWing // URL: https://www.acwing.com/problem/content/1034/ // Memory Limit: 64 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org) // %%%Skyqwq #include <bits/stdc++.h> //#define int long long #define help {cin.tie(NULL); cout.tie(NULL);} #define pb push_back #define fi first #define se second #define mkp make_pair using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef pair<LL, LL> PLL; template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; } template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; } template <typename T> void inline read(T &x) { int f = 1; x = 0; char s = getchar(); while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); } while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar(); x *= f; } const int N=100005,M=2e5+5; int n,d,m; char s[N]; int h[N],ne[M],e[M],idx; int pos[10]; int dfn[N],low[N],timestamp,stk[N],top,scc_cnt,id[N]; bool in_stk[N]; struct Op { int x,y; char a,b; }op[M]; void add(int a,int b) { e[idx]=b,ne[idx]=h[a],h[a]=idx++; } void tarjan(int x) { dfn[x]=low[x]=++timestamp; stk[++top]=x,in_stk[x]=true; for(int i=h[x];~i;i=ne[i]) { int y=e[i]; if(!dfn[y]) { tarjan(y); low[x]=min(low[x],low[y]); } else if(in_stk[y]) low[x]=min(low[x],dfn[y]); } if(low[x]==dfn[x]) { int y; scc_cnt++; do { y=stk[top--]; in_stk[y]=false; id[y]=scc_cnt; }while(y!=x); } } int get(int x,char a,int t) { a-='A'; char b=s[x]-'a'; if(((b+1)%3==a)^t)return x<<1|1; return x<<1; } char put(int x,int t) { int y=s[x]-'a'; return 'A'+(y+t)%3; } bool work() { memset(h,-1,sizeof h); memset(dfn,0,sizeof dfn); idx=timestamp=scc_cnt=0; for(int i=0;i<m;i++) { int x=op[i].x-1,y=op[i].y-1; char a=op[i].a,b=op[i].b; if(a+32!=s[x]) { if(b+32!=s[y])add(get(x,a,1),get(y,b,1)),add(get(y,b,0),get(x,a,0)); else add(get(x,a,1),get(x,a,0)); } } for(int i=0;i<2*n;i++) if(!dfn[i])tarjan(i); for(int i=0;i<n;i++) if(id[i<<1]==id[i<<1|1])return false; for(int i=0;i<n;i++) if(id[i<<1]<id[i<<1|1])putchar(put(i,1)); else putchar(put(i,2)); return true; } int main() { scanf("%d%d",&n,&d); scanf("%s",s); for(int i=0,j=0;s[i];i++) if(s[i]=='x')pos[j++]=i; scanf("%d",&m); for(int i=0;i<m;i++)scanf("%d %c %d %c",&op[i].x,&op[i].a,&op[i].y,&op[i].b); for(int i=0;i<1<<d;i++) { for(int j=0;j<d;j++) if(i>>j&1)s[pos[j]]='a'; else s[pos[j]]='b'; if(work())return 0; } puts("-1"); return 0; }

__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/16950045.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示