第 50 届 ICPC 国际大学生程序设计竞赛区域赛沈阳站 K 题思路分享(数学)

https://codeforces.com/gym/106252/problem/K

题意概述

给定笛卡尔平面上 \(n\) 只青蛙,当青蛙 \(i\) 被刺激时,会选择另一只青蛙 \(j\),跳跃到当前位置与青蛙 \(j\) 位置的对称点上,青蛙 \(j\) 成为下一个被刺激的青蛙.

给定 \(n\) 只青蛙的起点 \(P\) 和终点 \(Q\),以及第一只被刺激的青蛙,求出最后一只被刺激的青蛙,保证有解.

\(2\le n \le 10^5\).

思路

青蛙跳跃的过程非常复杂,考虑寻找与坐标相关的某个不变量.

当青蛙 \(i\) 跳跃到与青蛙 \(j\) 的对称点上时,\(x'=2x_j-x_i\)\(\Delta x = 2x_j-2x_i\).

\(\Delta x\) 系数是一致的,考虑构造 \(\phi(i) = \sum{x}-2x_i\).

跳跃前,被刺激青蛙为 \(i\)\(\phi(i)=\sum{x}-2x_i\);跳跃后,被刺激青蛙为 \(j\)\(\phi(j)=\sum{x}+\Delta x-2x_j=\sum{x}-2x_i=\phi(i)\).

于是 \(\phi(i)\) 为不变量,记第一只被刺激青蛙为 \(s\),最后一只为 \(t\),解

\[\begin{cases} \sum{P_x} - 2x_s = \sum{Q_x}-2x_t \\[1em] \sum{P_y} - 2y_s = \sum{Q_y}-2y_t \end{cases} \]

\[\begin{cases} x_t = \dfrac{\sum{Q_x}-\sum{P_x}+2x_s}{2} \\[1em] y_t = \dfrac{\sum{Q_y}-\sum{P_y}+2y_s}{2} \end{cases} \]

找到这样的终点坐标即可.

时间复杂度 \(\mathcal{O}(n)\).

代码

//author:kzssCCC

#include <bits/stdc++.h>
using namespace std;
using ll = long long;


void solve(){
	int n,s;
	cin >> n >> s;

	vector<pair<ll,ll>> P(n+1),Q(n+1);
	ll sumpx=0,sumqx=0,sumpy=0,sumqy=0;
	for (int i=1;i<=n;i++){
		cin >> P[i].first >> P[i].second >> Q[i].first >> Q[i].second;
		sumpx += P[i].first;
		sumpy += P[i].second;
		sumqx += Q[i].first;
		sumqy += Q[i].second;
	}	

	ll tx = (sumqx-sumpx+2*P[s].first)/2;
	ll ty = (sumqy-sumpy+2*P[s].second)/2;	
	for (int i=1;i<=n;i++){
		if (tx==Q[i].first && ty==Q[i].second){
			cout << i << '\n';
			return;
		}
	}
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	int t = 1;
	// cin >> t;
	while (t--) solve();

	return 0;
}
posted @ 2026-06-13 14:53  kzssCCC  阅读(13)  评论(0)    收藏  举报