【刷题笔记】[BalticOI 2024] Portal

【刷题笔记】[BalticOI 2024] Portal

\(Solution\)

先注意到,题目中的图形是许多的自相似图形,要求能满足要求的单位图形的最大面积
先考虑只有一维的情况, 设几个传送门的坐标为 \((a_i,0)\) ```

发现将整个图形平移后答案不会改变,所以不妨把一个传送门移动到 \((0,0)\)
可以发现单位图形的长度为所有点横坐标的 \(gcd\)
再考虑二维的情况,首先注意到一个性质
将点 \((x_i,y_i)\) 移动到 \((x_i-k\times{x_j}, y_i-k\times{y_j})\) 答案不变
看下面一个图

其中传送门的坐标为 \((0,0)\) , \((2,7)\) , \((3,2)\)
我们可以从 \((0,0)\), 不停传送到 \((3,2)\) 然后再走回来, 相当于不停地从 \((2,7)\) 往下走 \(2\) 个单位,再往左走 \(3\) 个单位。
于是我们就可以将所有的传送门变为以下三种形式 \((a,b)\) , \((x,0)\), \((0,0)\)
把点转移到 \(x\) 轴上的过程类似于辗转相除
最后的答案就是

\[gcd(x_i)\times{b} \]

如果答案为 \(0\) ,就说明没有宽的限制后没有长的限制,于是就会有无数个,输出 \(-1\)

\(Code\)

#include<bits/stdc++.h>
#define maxn 100010
#define ll __int128
using namespace std;
ll n, x[maxn], y[maxn], tx = -1, ty = -1;
ll ans = 0;
ll read(){
	char ch=getchar();
	ll s=0,f=1;
	while(ch>'9'||ch<'0'){
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		s=(s<<3)+(s<<1)+ch-'0';
		ch=getchar();
	}
	return s*f;
}
void write(ll x){
	if(x<0)putchar('-'),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+'0');
	return;
}
ll abs(ll a){
	if(a > 0) return a;
	return a = -a;
}
void work(ll x, ll y){
	while(ty){
		ll cur = y / ty;
		x -= cur * tx; y -= cur *ty;
		swap(x, tx); swap(y, ty);
	}
	ans = __gcd(ans, abs(tx));
	tx = x, ty = y;
}
int main(){
 	n = read();
	for(int i = 1; i <= n; i++){
		x[i] = read(); y[i] = read();
		if(i > 1){
			x[i] -= x[1];
			y[i] -= y[1];
		}
	}
	tx = x[2], ty = y[2];
	for(int i = 3; i <= n; i++){
		work(x[i], y[i]);
	}
	if(ans * abs(ty) != 0) write(ans * abs(ty));
	else write(-1);
	return 0;
}
posted @ 2024-11-19 17:13  SDFZ_GuoSN  阅读(1)  评论(0编辑  收藏  举报