qoj6562 First Last 题解

妙妙题。

首先不同字母数最多为 \(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;
} 
posted @ 2024-10-14 19:06  Creeper_l  阅读(12)  评论(0编辑  收藏  举报
  1. 1 イエスタデイ(翻自 Official髭男dism) 茶泡饭,春茶,kobasolo
  2. 2 世间美好与你环环相扣 柏松
  3. 3 True love tired
  4. 4 一笑江湖 (DJ弹鼓版) 闻人听書_
  5. 5 最好的安排 曲婉婷
  6. 6 星星在唱歌 司南
  7. 7 山川 李荣浩
  8. 8 On My Way Alan Walker
  9. 9 百战成诗 王者荣耀·100英雄官方群像献礼歌
  10. 10 雪 Distance Capper / 罗言
  11. 11 Edamame bbno$ / Rich Brian
  12. 12 半生雪 七叔-叶泽浩
  13. 13 Catch My Breath Kelly Clarkson
  14. 14 Love Is Gone SLANDER / Dylan Matthew
  15. 15 Endless Summer Alan Walker / Zak Abel
  16. 16 悬溺 葛东琪
  17. 17 风吹丹顶鹤 葛东琪
  18. 18 Normal No More TYSM
  19. 19 哪里都是你 队长
  20. 20 Stronger Kelly Clarkson
  21. 21 廖俊涛
  22. 22 消愁 毛不易
  23. 23 The Runner Yubik
  24. 24 踏山河 七叔-叶泽浩
  25. 25 Waiting For Love Avicii
  26. 26 在你的身边 盛哲
  27. 27 Dream It Possible Delacey
  28. 28 凄美地 郭顶
  29. 29 满天星辰不及你 ycc
  30. 30 侧脸 于果
  31. 31 阿拉斯加海湾 蓝心羽
  32. 32 虞兮叹 闻人听書_
  33. 33 离别开出花 就是南方凯
  34. 34 盗墓笔记·十年人间 李常超 (Lao乾妈)
True love - tired
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.