首页 > 其他分享 >qoj6562 First Last 题解

qoj6562 First Last 题解

时间:2024-10-14 18:59:31浏览次数:1  
标签:Last int 题解 make flag 自环 pair qoj6562 dp

妙妙题。

首先不同字母数最多为 \(3\)。我们把每一个字母看成一个点。对于每一个字符串,首个字母朝末尾字母连一条有向边。那么问题变为了给定一张有向图,从某个点出发,每次走一条边,且边不能重复,不能走的人输。问哪方有必胜策略。

先不考虑时间复杂度,那么这个可以直接爆搜。但是肯定会 T,考虑剪枝。

会发现一些神奇的事情:

  • 若点 \(u\) 有 \(2\) 个自环,可以把这两个自环删掉。
  • 若 \(u \to v\) 有边,\(v \to u\) 也有边,可以同时删去这两条边。

证明第一个:若先手走了自环,那后手一定也可以走一次自环就回到初始状态了。第二个证明同理。

于是边的情况就很少了,可以直接记忆化搜索求出答案。

//dzzfjldyqqwsxdhrdhcyxll
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN = 1e3 + 10;
int n,cnt,ans,a[5][5],b[5][5];
vector <int> now;
map <char,int> mp;
map <pair <vector <int>,int>,bool> dp;
string s[MAXN];
inline int dfs(vector <int> v,int u) {
	if(dp.count(make_pair(v,u))) return dp[make_pair(v,u)];
	bool flag = true;
	for(int i = 0;i < 9;i++) flag &= (v[i] == 0);
	if(flag == true) {
		return dp[make_pair(v,u)] = 0;
	}
	for(int j = 1;j <= 3;j++) {
		if(v[(u - 1) * 3 + j - 1] > 0) {
			v[(u - 1) * 3 + j - 1]--;
			flag |= !dfs(v,j);
			v[(u - 1) * 3 + j - 1]++;
		}
	}
	return dp[make_pair(v,u)] = flag;
}
signed main() {
	cin >> n;
	for(int i = 1;i <= n;i++) cin >> s[i];
	for(int i = 1;i <= n;i++) {
		#define s s[i]
		if(mp[s[0]] == 0) mp[s[0]] = ++cnt;
		if(mp[s[s.length() - 1]] == 0) mp[s[s.length() - 1]] = ++cnt;
		a[mp[s[0]]][mp[s[s.length() - 1]]]++;
		#undef s
	}
	for(int i = 1;i <= 3;i++)
		for(int j = 1;j <= 3;j++) b[i][j] = a[i][j];
 	
	for(int i = 1;i <= 3;i++) {
		for(int j = 1;j <= 3;j++) {
			for(int p = 1;p <= 3;p++) {
				for(int q = 1;q <= 3;q++) {
					a[p][q] = b[p][q];
				}
			}
			if(a[i][j] == 0) continue;
			a[i][j]--;
			for(int p = 1;p <= 3;p++) a[p][p] %= 2;
			for(int p = 1;p <= 3;p++) {
				for(int q = p + 1;q <= 3;q++) {
					int mn = min(a[p][q],a[q][p]);
					a[p][q] -= mn;
					a[q][p] -= mn;
				}
			}	
			now.clear();
			for(int p = 1;p <= 3;p++) {
				for(int q = 1;q <= 3;q++) {
					now.emplace_back(a[p][q]);
					if(a[p][q] != 0) {
					}
				}
			}
			bool flag = dfs(now,j) ^ 1;
			ans += flag * b[i][j];
		}
	}
	cout << ans;
	return 0;
} 

标签:Last,int,题解,make,flag,自环,pair,qoj6562,dp
From: https://www.cnblogs.com/Creeperl/p/18464785

相关文章

  • 题解:P11063 【MX-X4-T3】「Jason-1」数对变换
    ProblemLink【MX-X4-T3】「Jason-1」数对变换题外话场上把贪心注重在一个奇怪地方了,导致交的时候已经有\(9\)个人\(\textcolor{green}{AC}\)了(哭)。题意简述对于数对\((x,y)\),你可以执行以下两种变换:类型1:取\(1\lek\lex\),令\((x,y)\gets(\lfloor\frac{x}{k}......
  • 题解:P10370 「LAOI-4」Mex Tower (Hard ver.)
    ProblemLink「LAOI-4」MexTower(Hardver.)题意给定一个长度为$n$的序列$a$,求序列的$\operatorname{Mex}$值是否大于等于其他所有长度为$n$的自然数序列的$\operatorname{Mex}$值。Solution不难发现,两个数或一个序列的$\operatorname{Mex}$一定是......
  • 题解:擬二等辺三角形
    ProblemLink擬二等辺三角形题面翻译定义一个三角形为“伪等腰三角形”需满足以下三个条件:三边长度都为自然数。三边长度各不相同。有其中两条边的长度之差为\(1\)。现在给你一个数\(n\),求周长小于等于\(n\)的“伪等腰三角形”个数,答案对\(1000000007\)取模......
  • 题解:AT_abc370_c [ABC370C] Word Ladder
    题目传送门luogu观看简要题意给两个序列\(S\)和\(T\),输出的第一个数是它能改变的总个数,后面跟着的第\(i\)个是改变\(i\)个数之后,字典序最小的结果。思路当\(S\)与\(T\)相等的话,那就无法改变了,直接输出\(0\)。对于总数只要\(T_i\neS_i\)那它就可以改,所以只......
  • 题解:P1660 数位平方和
    ProblemLinkStep1:“定义\(S(n)\)表示\(n\)个的各个数位的\(k\)次方的和。”数位的\(k\)次方,我们可以通过快速幂求出,为了节省时间,我们可以定义一个\(a\)数组,来表示\(0\sim9\)区间中各数字\(k\)次方的值。然后我们通过定义一个\(s\)数组来存储\(0\sim4\times......
  • 题解:P7356 「PMOI-1」游戏
    ProblemLink「PMOI-1」游戏题意给你一个胜利规则为黑白白白的棋类游戏,你执白,黑先行且第一步必下\((0,0)\),双方皆可放弃落子且落子坐标必须为自然数,请在4步内获胜。思路在自己与自己对下几局之后,有几个显然的发现:黑棋会尽量阻止你4步获胜。在你不会再下一步就获......
  • 题解:AT_agc027_b [AGC027B] Garbage Collector
    ProblemLink[AGC027B]GarbageCollector题意原题翻译已经很不错了,这里不再赘述。思路推论:每次取的垃圾数量应尽可能均分。证明如图,假设有\(4\)个垃圾需要被捡起,有两种取法:取一号垃圾+取二三四号垃圾。取一二号垃圾+取二三号垃圾。前者所需能量为:\(\display......
  • [2024领航杯] Pwn方向题解 babyheap
      [2024领航杯]Pwn方向题解babyheap前言:当然这个比赛我没有参加,是江苏省的一个比赛,附件是XiDP师傅在比赛结束之后发给我的,最近事情有点多,当时搁置了一天,昨天下午想起来这个事情,才开始看题目,XiDP师傅说是2.35版本的libc,确实高版本libc的却棘手,我经验太浅了调试半天,最后让我们......
  • CF360B题解
    简述题意定一个数列\(a\),可以对其中的元素做至多\(k\)次修改,每次修改可以将数列中的一个数改成另一个。求经过修改后,\(max_{i=1}^{n}|a_i-a_{i-1}|\)思路考虑二分答案,对于check函数,我们可以利用dp进行求解。由于修改不太好想,我们可以把问题转换为让不被修改的数最多......
  • CF1814B. Long Legs 题解 枚举
    题目链接:https://codeforces.com/problemset/problem/1814/B题目大意有一个无限大的二维平面,我们用\((x,y)\)来表示平面中横坐标为\(x\)纵坐标为\(y\)的那个位置。一个机器人被放置在该二维平面的\((0,0)\)位置中。该机器人的腿长可以调节。最初,它的腿长为\(1\)。......