【刷题笔记】[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;
}