D - Switch Seats

题目链接:https://atcoder.jp/contests/abc399/tasks/abc399_d

题意:

给定一个序列每个值都是成对出现,问有多少个(a,b)对满足a,a不相邻,b,b不相邻且交换一个a和一个b能使a,a相邻,b,b相邻

思路:

先确定每个数的两个位置,发现满足条件的(a,b)要满足a和b相邻 x 2
即a,b...b,a
a,b... a,b
b,a... a,b
b,a... b,a
所以枚举ai ,ai+1
只要有一个相邻的数,continue
判断两个(a,b)是否相邻,可以排序后比较
为了满足(a,b)对的独特性,需要用set去重

void solve(){
	int n;cin>>n;
	vector<int>a(2*n+2);
	rep(i,1,2*n)cin>>a[i];
	
	vector<int>pos1(n+1);
	vector<int>pos2(n+1);
	int cnt=0;
	for(int i=1;i<=2*n;i++){
		if(!pos1[a[i]])pos1[a[i]]=i;
		else pos2[a[i]]=i;
	}
	set<pii>st;
	for(int i=1;i<=2*n-1;i++){
		int pos_a=pos1[a[i]],pos_b=pos1[a[i+1]];
		if(pos2[a[i]]==pos1[a[i]]+1||pos2[a[i+1]]==pos1[a[i+1]]+1)continue;
		vector<int>v{pos1[a[i]],pos1[a[i+1]],pos2[a[i]],pos2[a[i+1]]};
		sort(v.begin(),v.end());
		if(v[0]+1==v[1]&&v[2]+1==v[3]){
			if(st.count({a[i],a[i+1]})||st.count({a[i+1],a[i]}))continue;
			st.insert({a[i],a[i+1]});
		}
	}
	cout<<st.size()<<endl;
}
posted @ 2025-03-30 12:05  Marinaco  阅读(57)  评论(0)    收藏  举报
//雪花飘落效果