首页 > 其他分享 >[NOI2017] 游戏

[NOI2017] 游戏

时间:2024-08-22 11:39:44浏览次数:10  
标签:游戏 pt int text break 枚举 NOI2017 SAT

先来讲一下到底什么叫K-SAT

先来看看2-SAT的准确定义

image

那么对于k-SAT,不是说每个集合就有\(k\)个元素了(每个集合仍然只有两个元素,因为布尔变量的取值只有\(0\)和\(1\)),而是说给出的限制条件涉及\(k\)个元素,比如3-SAT

image

那么对于这道题目,如果不考虑\(\text{x}\)的话,就是一个裸的2-SAT问题;发现\(d\)很小,考虑\(\text{x}\)的话,枚举即可(由于也要让\(\text{x}\)只包含两个元素,所以是枚举的不能用哪一类型的赛车)。具体见这篇题解

但是要讲一下细节

一.最好先将每个地图可以用的赛车类型用字符串存下来(按字典序排序),比如pt[i]="AB"表示第\(i\)个地图可以用的赛车类型为\(A\)和\(B\),然后在加边的时候,再去判断是\(i\)还是\(i+n\),要简单很多

二.不要用STL,用手写栈

三.如果对每个\(\text{x}\)枚举三种情况的话,理论复杂度就会炸掉,这个时候就要思考能不能只枚举两种情况,另外一种情况已经被包含了

四.也是卡常新操作:将链式前向星清空一部分。我们枚举的时候,每一次都要情况链式前向星的话,常熟太大了;此时我们可以先将所有不涉及\(\text{x}\)的边全部加入,然后在枚举的时候不删除这些边,只删除新加入的边(涉及\(\text{x}\)的边)即可

#include<bits/stdc++.h>
using namespace std;
const int N=5e4+10,M=1e5+10;
int n,m,d;
int visitime;
int dfn[N<<1],low[N<<1];
int pos[10];
int s[N<<1],tp;
char S[N];
bool instack[N<<1];
string pt[N];
int scc;
int belong[N<<1];
int cnt,Cnt;
int End[M<<2],Last[N<<1],Next[M<<2];
int num,edge[M];
int u[M],v[M];
char a[M],b[M];
void add(int x,int y)
{
	End[++Cnt]=y,Next[Cnt]=Last[x],Last[x]=Cnt;
}
void tarjan(int u)
{
    dfn[u]=low[u]=++visitime;
    s[++tp]=u;instack[u]=1;
    for(int i=Last[u];i;i=Next[i])
    {
        int v=End[i];
        if(!dfn[v])
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(dfn[v]&&instack[v])
        {
            low[u]=min(low[u],dfn[v]);
        }
     } 
    if(low[u]==dfn[u])
    {
        ++scc;
        int v;
        do{
            v=s[tp--];instack[v]=0;
            belong[v]=scc;
        }while(v!=u);
    }
}
void del(int x)
{
    Cnt--;
    Last[x]=Next[Last[x]];
}
int main()
{
	bool mark=0;
	scanf("%d%d",&n,&d);
	scanf("%s",S);
	for(int i=1;i<=n;i++)
	switch(S[i-1])
	{
		case 'a':pt[i]="BC";break;
		case 'b':pt[i]="AC";break;
		case 'c':pt[i]="AB";break;
		case 'x':pos[++cnt]=i;break;//pos记录每个x的位置 
	} 
	scanf("%d",&m);
	for(int i=1;i<=m;i++)
	scanf("%d %c%d %c\n",&u[i],&a[i],&v[i],&b[i]);
	for(int i=1;i<=m;i++)
	if(S[u[i]-1]!='x'&&S[v[i]-1]!='x')
	{
	    if(pt[u[i]][0]==a[i])
		{
			if(pt[v[i]][0]==b[i]) add(u[i],v[i]),add(v[i]+n,u[i]+n);
			else if(pt[v[i]][1]==b[i]) add(u[i],v[i]+n),add(v[i],u[i]+n);
			else add(u[i],u[i]+n);
		}
		else if(pt[u[i]][1]==a[i])
		{
			if(pt[v[i]][0]==b[i]) add(u[i]+n,v[i]),add(v[i]+n,u[i]);
			else if(pt[v[i]][1]==b[i]) add(u[i]+n,v[i]+n),add(v[i],u[i]);
			else add(u[i]+n,u[i]);
		}
	}
	else edge[++num]=i;
	for(int i=0;i<(1<<cnt);i++)
	{
		visitime=scc=0;
		tp=0;
		for(int j=1;j<=(n<<1);j++) 
		dfn[j]=low[j]=instack[j]=belong[j]=0;
		for(int j=1;j<=cnt;j++)
		switch(i>>(j-1)&1)
		{
			case 0:pt[pos[j]]="BC";break;
			case 1:pt[pos[j]]="AC";break;
		} 
		for(int k=1,j=edge[k];k<=num;k++,j=edge[k])
		if(pt[u[j]][0]==a[j])
		{
			if(pt[v[j]][0]==b[j]) add(u[j],v[j]),add(v[j]+n,u[j]+n);
			else if(pt[v[j]][1]==b[j]) add(u[j],v[j]+n),add(v[j],u[j]+n);
			else add(u[j],u[j]+n);
		}
		else if(pt[u[j]][1]==a[j])
		{
			if(pt[v[j]][0]==b[j]) add(u[j]+n,v[j]),add(v[j]+n,u[j]);
			else if(pt[v[j]][1]==b[j]) add(u[j]+n,v[j]+n),add(v[j],u[j]);
			else add(u[j]+n,u[j]);
		}
		for(int j=1;j<=(n<<1);j++)
		if(!dfn[j]) tarjan(j);
		bool flag=1;
		for(int j=1;j<=n;j++)
		if(belong[j]==belong[j+n])
		{
			flag=0;
			break;
		}
		for(int k=1,j=edge[k];k<=num;k++,j=edge[k])//删边操作,想一下为什么成立 
		if(pt[u[j]][0]==a[j])
		{
			if(pt[v[j]][0]==b[j]) del(u[j]),del(v[j]+n);
			else if(pt[v[j]][1]==b[j]) del(u[j]),del(v[j]);
			else del(u[j]);
		}
		else if(pt[u[j]][1]==a[j])
		{
			if(pt[v[j]][0]==b[j]) del(u[j]+n),del(v[j]+n);
			else if(pt[v[j]][1]==b[j]) del(u[j]+n),del(v[j]);
			else del(u[j]+n);
		}
		if(!flag) continue; 
		mark=1;
		for(int j=1;j<=n;j++)
		printf("%c",belong[j]>belong[j+n]?pt[j][1]:pt[j][0]);
		break;
	}
	if(!mark) puts("-1");
	return 0;
}

标签:游戏,pt,int,text,break,枚举,NOI2017,SAT
From: https://www.cnblogs.com/dingxingdi/p/18373511

相关文章

  • 《幕府将军2》游戏受挫:shogun2.dll错误详尽诊断与高效修复指南
    解决《幕府将军2》游戏中shogun2.dll文件丢失的问题,可以按照以下步骤操作:1.重新安装游戏:•首先,尝试通过Steam验证游戏文件完整性(库中右击游戏->属性->本地文件->验证游戏文件完整性)。如果这不能解决问题,考虑完全卸载并重新安装游戏,确保获得所有必要文件。2.手动下载shogun2......
  • 分支和循环以及猜数字游戏的实现
    分支和循环以及猜数字游戏的实现目录随机书生成randsrandtime设置随机数的范围猜数字游戏的实现随机书生成randC语言中有一个函数叫rand函数,它可以生成随机数,代码格式如下:intrand(void)rand函数会返回一个伪随机数,这个随机数的范围是在0~RAND_MAX之间,这个RAND_MA......
  • 游戏试玩挂机项目
     项目介绍:外面最新项目游戏试玩平台全自动挂机项目可无限放大设备需求:电脑云手机+单窗口单IP 获取:百度网盘请输入提取码百度网盘为您提供文件的网络备份、同步和分享服务。空间大、速度快、安全稳固,支持教育网加速,支持手机端。注册使用百度网盘即可享受免费存储空间htt......
  • 《黑神话:悟空》爆火,如何把握游戏行业机遇?
    “我们曾在许多国外的游戏大作里,拯救过不同的世界,但唯独没有在我们自己的故事里,当过一次超级英雄,这一次,我只想做一个齐天大圣,圆一次儿时的梦。”8月20日上午10点,国产3A游戏《黑神话:悟空》正式上线全球发售,这是一款由中国游戏开发商游戏科学(GameScienceStudio)开发的动作角色扮......
  • 力扣面试经典算法150题:跳跃游戏
    跳跃游戏今天的题目是力扣面试经典150题中的数组的中等难度题:跳跃游戏。题目链接:https://leetcode.cn/problems/jump-game/description/?envType=study-plan-v2&envId=top-interview-150题目描述给定一个非负整数数组nums,你最初位于数组的第一个下标,即nums[0]。数......
  • 《黑神话:悟空》游戏启动时提示“找不到framedyn.dll文件”该怎么解决?黑神话悟空游戏闪
    在《黑神话:悟空》游戏启动时,若遇到“找不到framedyn.dll文件”的提示,不要惊慌。可以尝试从可靠渠道重新下载该文件并放置到正确位置。也可使用系统修复工具检查修复,确保游戏能够正常启动运行。需注意操作要谨慎,以免引发其他问题。本篇将为大家带来提示“找不到framedyn.dll文件......
  • “风色幻想XX:交错轨迹游戏卡顿:从解决d3dx9_xx.dll缺失开始——风色幻想XX优化指南
    《风色幻想XX:交错轨迹》作为一款深受玩家喜爱的角色扮演游戏,以其丰富的剧情、独特的角色设定和精美的画面赢得了广泛的赞誉。然而,在游戏过程中,部分玩家可能会遇到游戏卡顿的问题,这不仅影响了游戏体验,还可能让玩家错失精彩的剧情和战斗瞬间。在众多导致游戏卡顿的因素中,d3dx9_xx......
  • 单词游戏 欧拉回路
    //单词游戏.cpp:此文件包含"main"函数。程序执行将在此处开始并结束。///*http://ybt.ssoier.cn:8088/problem_show.php?pid=1528https://loj.ac/p/10106来自ICPCCERC1999/2000,有改动。有N个盘子,每个盘子上写着一个仅由小写字母组成的英文单词。你需要给这些盘......
  • 英伟达首个AI NPC入驻游戏,国产大作,4B模型只需2G显存
    点击访问我的技术博客https://ai.weoknow.comhttps://ai.weoknow.com玩家都在问:游戏什么时候上线?大模型驱动的游戏NPC终于落地了。今天凌晨,英伟达放出一段游戏demo。现在打游戏,你可以用语音对话的方式和NPC交流,了解关卡目标、优化装备配置,随后调整武器配色开......
  • 《黑神话悟空》游戏录屏不卡顿秘籍,流畅记录每一刻精彩
    万众瞩目的国产游戏大作《黑神话:悟空》昨日已经上线,无数玩家已经迫不及待想要记录下自己这段史诗级冒险中的每一个精彩瞬间,但想要完美捕捉并分享这些画面,不仅需要精湛的游戏技巧,还需要对录屏设置进行优化,下面就一起来看看怎么设置《黑神话:悟空》的录屏吧。一、选择合适的录......