首页 > 其他分享 >1032. 游戏

1032. 游戏

时间:2022-12-04 16:24:32浏览次数:69  
标签:游戏 int 地图 赛车 使用 1032 SAT

题目链接

1032. 游戏

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

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

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

小 \(L\) 的赛车有三辆,分别用大写字母 \(A、B、C\) 表示。

地图一共有四种,分别用小写字母 \(x、a、b、c\) 表示。

其中,赛车 \(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,h_i,j,h_j\)) 来描述,表示若在第 \(i\) 场使用型号为 \(h_i\) 的车子,则第 \(j\) 场游戏要使用型号为 \(h_j\) 的车子。

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

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

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

输入格式

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

输入第二行为一个字符串 \(S\) 。

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

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

接下来 \(m\) 行,每行包含一个四元组 \(i,h_i,j,h_j\) ,其中 \(i, j\) 为整数,\(h_i,h_j\) 为字符 \(A 、B\) 或 \(C\),含义见题目描述。

输出格式

输出一行。

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

若有解,则包含一个长度为 \(n\) 的仅包含大写字母 \(A、B、C\) 的字符串,表示小 \(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\) 场游戏分别安排赛车 \(A、B、A\) 可以满足所有条件。

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

但依次安排赛车为 \(AAB\) 或 \(ABC\) 时,因为不能满足所有条件,所以不被视为正确答案。

解题思路

2-SAT

对于 \(a\),其只能使用 \(A\) 或 \(B\),对于 \(b\),其只能使用 \(a\) 或 \(c\),对于 \(c\),其只能使用 \(A\) 或 \(B\),对于 \(x\),其可以使用 \(A\) 或 \(B\) 或 \(C\),显然这是一个 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\) 的场次来说,其一定是选 \(B\) 或 \(C\),或者选 \(A\) 或 \(C\),即其可以等价于两种 2-SAT,共有 \(2^d\) 种组合,这样就将问题完全转化为 2-SAT 问题

  • 时间复杂度:\(O(2^d\times (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;
}

标签:游戏,int,地图,赛车,使用,1032,SAT
From: https://www.cnblogs.com/zyyun/p/16950045.html

相关文章

  • 设计点灯游戏前的总结
    设计点灯游戏前的总结因c语言程序设计实践课,恰好选择了对点灯游戏的实现,则我们先来归纳如何去求点灯游戏的方案。零——前置芝士点灯游戏简介一层大楼共有\(n×n\)个......
  • SpringCloud游戏平台改造-Day1
    Day1今天主要的工作是有,新建项目结构(后期可能会根据实际情况修改),实现了登录注册API项目思路目前的项目思路为以下几部分:GameAuth:用来提供用户登录注册接口,认证接口......
  • SpringCloud游戏平台改造-Day2
    Day2今天主要目的是接入SpringSecurity和JWT,不多说开干!Day1Day2接入SpringSecurityStep1实现来自SpringSecurity的UserDetailService接口,实现它的loaduserByUser......
  • js-day05-猜数字游戏和随机点名升华
     猜数字游戏<script>    //随机数    functiongetRandom(min,max){      returnMath.floor(Math.random()*(max-min+1))+min......
  • 猜数字游戏
    前言:在介绍猜数字游戏时,上一篇博客忘记写了,我们先来了解一下goto语句1.goto语句忠告:慎用goto语句C语言中提供了可以随意滥用的goto语句和标记跳转的标号。从理论上goto语......
  • 制作一个跳跃的小球游戏
    #-*-coding:utf-8-*-importsys#导入sys模块importpygame#导入pygame模块pygame.init()#初始化pygamesize=width,height=640,480#设置窗口s......
  • python游戏编程
     一,实验目的Pygame是跨平台Python模块,专为电子游戏设计(包含图像、声音),创建在SDL基础上,允许实时电子游戏研发而不被低级语言舒服。基于这一设想,所有需要的游戏功能和理......
  • 第13章 pygame游戏编程
    一、实验目的和要求学会Pygame的基本应用二、实验环境软件版本:Python3.1064_bit三、实验过程1、实例1:制作一个跳跃的小游戏(1)代码如下:#-*-coding:utf-8-*-im......
  • Pygame小球游戏
    importsysimportpygamepygame.init()size=width,height=1000,800screen=pygame.display.set_mode(size)color=(0,0,0)ball=pygame.image.load("ball.......
  • 第十三章 Pygame游戏编程
     实例01:制作一个跳跃的小球小游戏 创建一个游戏窗口,然后在窗口内创建一个小球,以一定的速度移动小球,当小球碰到游戏窗口的边缘时,小球弹回,继续移动。  代码如下......