• [LOJ#2305]「NOI2017」游戏


    [LOJ#2305]「NOI2017」游戏

    试题描述

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

    小 L 的赛车有三辆,分别用大写字母 (A)(B)(C) 表示。地图一共有四种,分别用小写字母 (x)(a)(b)(c) 表示。

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

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

    (n) 场游戏的地图可以用一个小写字母组成的字符串描述。例如:(S = exttt{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

    输入示例

    3 1
    xcc
    1
    1 A 2 B
    

    输出示例

    ABA
    

    数据规模及约定

    题解

    枚举那 (d)(x) 的地图用 (A) 还是用 ({ B, C }),变成 2-SAT 模型。

    #include <bits/stdc++.h>
    using namespace std;
    #define rep(i, s, t) for(int i = (s), mi = (t); i <= mi; i++)
    #define dwn(i, s, t) for(int i = (s), mi = (t); i >= mi; i--)
    
    int read() {
    	int x = 0, f = 1; char c = getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
    	return x * f;
    }
    
    #define maxn 100010
    #define maxm 200010
    
    char Map[maxn], Ans[maxn];
    int n, m, D, Did[maxn], CntP;
    struct Clause {
    	int a, ta, b, tb;
    	Clause() {}
    	Clause(int _1, int _2, int _3, int _4): a(_1), ta(_2), b(_3), tb(_4) {}
    } cs[maxm];
    bool NeverHappen(int a, int ta, int s) {
    	if(Map[a] == ta + 'a') return 1;
    	if(ta && Map[a] == 'x' && (s >> Did[a] & 1)) return 1;
    	if(!ta && Map[a] == 'x' && !(s >> Did[a] & 1)) return 1;
    	return 0;
    }
    
    struct Point {
    	int id;
    	Point(): id(0) {}
    	int p() { return id ? id : id = ++CntP; }
    } use[maxn][3];
    int sumTp[maxn];
    
    namespace G {
    	int m, head[maxn], nxt[maxm], to[maxm];
    	void clear() {
    		m = 0; memset(head, 0, sizeof(head));
    		return ;
    	}
    	void AddEdge(int a, int b) {
    		to[++m] = b; nxt[m] = head[a]; head[a] = m;
    		return ;
    	}
    	
    	int dfn[maxn], low[maxn], clo, scno[maxn], cnts, S[maxn], top;
    	void init() {
    		memset(dfn, 0, sizeof(dfn));
    		memset(low, 0, sizeof(low));
    		clo = 0;
    		memset(scno, 0, sizeof(scno));
    		cnts = 0;
    		return ;
    	}
    	void dfs(int u) {
    		dfn[u] = low[u] = ++clo;
    		S[++top] = u;
    		for(int e = head[u]; e; e = nxt[e]) {
    			if(scno[to[e]]) continue;
    			if(dfn[to[e]]) low[u] = min(low[u], dfn[to[e]]);
    			else dfs(to[e]), low[u] = min(low[u], low[to[e]]);
    		}
    		if(low[u] == dfn[u]) {
    			cnts++;
    			while(S[top] != u) scno[S[top--]] = cnts;
    			scno[S[top--]] = cnts;
    		}
    		return ;
    	}
    }
    
    int main() {
    	n = read(); D = read();
    	scanf("%s", Map + 1);
    	m = read();
    	rep(i, 1, m) {
    		int a = read(), b;
    		char cha[5], chb[5];
    		scanf("%s", cha);
    		b = read();
    		scanf("%s", chb);
    		cs[i] = Clause(a, cha[0] - 'A', b, chb[0] - 'A');
    	}
    	
    	int cD = 0;
    	rep(i, 1, n) if(Map[i] == 'x') Did[i] = cD++;
    	int all = (1 << D) - 1;
    	rep(s, 0, all) {
    		CntP = 0;
    		memset(use, 0, sizeof(use));
    		G::clear();
    		
    		rep(i, 1, n) if(Map[i] != 'x') {
    			if(Map[i] == 'a') use[i][1].p(), use[i][2].p(), sumTp[i] = 3;
    			if(Map[i] == 'b') use[i][0].p(), use[i][2].p(), sumTp[i] = 2;
    			if(Map[i] == 'c') use[i][0].p(), use[i][1].p(), sumTp[i] = 1;
    		}
    		else {
    			if(s >> Did[i] & 1) G::AddEdge(use[i][1].p(), use[i][0].p()), sumTp[i] = 1;
    			else use[i][1].p(), use[i][2].p(), sumTp[i] = 3;
    		}
    		
    		rep(i, 1, m) {
    			if(NeverHappen(cs[i].a, cs[i].ta, s)) continue;
    			if(NeverHappen(cs[i].b, cs[i].tb, s)) G::AddEdge(use[cs[i].a][cs[i].ta].p(), use[cs[i].a][sumTp[cs[i].a]-cs[i].ta].p());
    			else
    				G::AddEdge(use[cs[i].a][cs[i].ta].p(), use[cs[i].b][cs[i].tb].p()),
    				G::AddEdge(use[cs[i].b][sumTp[cs[i].b]-cs[i].tb].p(), use[cs[i].a][sumTp[cs[i].a]-cs[i].ta].p());
    		}
    		G::init();
    		rep(i, 1, CntP) if(!G::dfn[i]) G::dfs(i);
    		
    		bool ok = 1;
    		rep(i, 1, n) {
    			if(sumTp[i] == 3) {
    				if(G::scno[use[i][1].p()] == G::scno[use[i][2].p()]) { ok = 0; break; }
    				else Ans[i] = G::scno[use[i][1].p()] < G::scno[use[i][2].p()] ? 'B' : 'C';
    			}
    			if(sumTp[i] == 2) {
    				if(G::scno[use[i][0].p()] == G::scno[use[i][2].p()]) { ok = 0; break; }
    				else Ans[i] = G::scno[use[i][0].p()] < G::scno[use[i][2].p()] ? 'A' : 'C';
    			}
    			if(sumTp[i] == 1) {
    				if(G::scno[use[i][0].p()] == G::scno[use[i][1].p()]) { ok = 0; break; }
    				else Ans[i] = G::scno[use[i][0].p()] < G::scno[use[i][1].p()] ? 'A' : 'B';
    			}
    		}
    		if(ok) return Ans[n+1] = 0, puts(Ans + 1), 0;
    	}
    	puts("-1");
    	
    	return 0;
    }
    
  • 相关阅读:
    管理Linux软件——aptitude
    管理Linux软件——apt
    /etc/apt/sources.list 和 /etc/apt/sources.list.d
    JSR303参数校验正则表达式的莫名其妙的错误
    HighCharts 动态设置 series
    template might not exist or might not be accessible by any of the configured Template Resolvers
    springboot 热部署替代方式
    如果访问国外站点慢的话,可以多切换一下运营商,比如开热点。
    当 springboot 部署war包,tomcat报一堆无法解决的问题时
    thymeleaf在开发环境正常,但用jar运行时报错 Error resolving template template might not exist or might not be accessible
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/9159751.html
Copyright © 2020-2023  润新知