https://codeforces.com/problemset/problem/1299/B
这道水题想了一年。。。。
其实看样例都能猜出来,让(0,0)在凸包的边界上移动,最后得到的图形要与原图形相似,就是每条边的长度比例不能边,而且不能多出新的边,也不能与原边不平行。
可以想到,让(0,0)在一条边a上移动时,那么距离这条边最远的点就会移动成新的图形的一条边,如果最远的点是一个点而不是一条边上的点,那么那个地方就多出了一条边,肯定不相似的,所以最远的必须是一条平行边上的点。
设最远为b,然后可以想到对应的边长度是La+Lb,而反过来再b上移动时,对应边也是La+Lb,因为边的比例要相同,所以La=Lb
#include<bits/stdc++.h>
using namespace std;
const int maxl=3e5+10;
int n,m,ans;
struct point
{
int x,y;
point(int a=0,int b=0)
{
x=a;y=b;
}
point operator - (const point &b)const
{
return point(x-b.x,y-b.y);
}
}a[maxl];
inline long long det(point a,point b)
{
return 1ll*a.x*b.y-1ll*a.y*b.x;
}
inline void prework()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i].x,&a[i].y);
a[n+1]=a[1];
}
inline void mainwork()
{
if(n&1)
return;
ans=1;int l; point x,y;
for(int i=1;i<=n/2;i++)
{
l=n/2+i;
x=a[i+1]-a[i];
y=a[l+1]-a[l];
if((x.x!=y.x && x.x!=-y.x) || (x.y!=y.y && x.y!=-y.y))
{
ans=0;
return;
}
}
}
inline void print()
{
if(ans)
puts("YES");
else
puts("NO");
}
int main()
{
int t=1;
//scanf("%d",&t);
for(int i=1;i<=t;i++)
{
prework();
mainwork();
print();
}
return 0;
}
本文深入解析了Codeforces编号为1299/B的题目,通过移动原点(0,0)于凸包边界,探讨如何保持图形与原图相似,确保边长比例不变且无新增或平行边变化。代码实现采用C++,利用点运算和向量分析验证边的相等性和方向一致性。
315

被折叠的 条评论
为什么被折叠?



