BZOJ1527 : [POI2005]Pun-point

求出重心,然后把所有点关于重心极角排序,极角相同的按到重心距离从大到小排序。

按极角序依次扫描,得到相邻两个向量的夹角以及长度之比,看成字符串。

若两个字符串循环同构,则两个点集相似,KMP判断即可。

时间复杂度$O(n\log n)$。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=25010;
const double eps=1e-10;
int T,l,i,j,k,nxt[N];
inline int sgn(double x){
  if(x<-eps)return -1;
  if(x>eps)return 1;
  return 0;
}
struct P{
  double x,y,o;
  P(){}
  P(double _x,double _y){x=_x,y=_y;}
  P operator+(const P&b){return P(x+b.x,y+b.y);}
  P operator-(const P&b){return P(x-b.x,y-b.y);}
  P operator/(double b){return P(x/b,y/b);}
  bool operator==(const P&b){return !sgn(x-b.x)&&!sgn(y-b.y);}
  bool operator!=(const P&b){return sgn(x-b.x)||sgn(y-b.y);}
  void cal(){o=atan2(y,x);}
  double operator*(const P&b){return x*b.x+y*b.y;}
  double len(){return sqrt(x*x+y*y);}
  double lensqr()const{return x*x+y*y;}
}a[N],b[N],O;
inline bool cmp(const P&a,const P&b){
  if(!sgn(a.o-b.o))return a.lensqr()>b.lensqr();
  return a.o<b.o;
}
struct Set{
  int n,m;P f[N];
  void init0(){
    n=l;
    for(i=0;i<n;i++)a[i]=b[i];
  }
  void init1(){
    n=l;
    for(i=0;i<n;i++)a[i]=b[i],a[i].x*=-1;
  }
  void init(){
    O=P(0,0);
    for(i=0;i<n;i++)O=O+a[i];
    O=O/((double)n);
    for(i=j=m=0;i<n;i++)if(a[i]==O)m++;else a[j++]=a[i];
    n=j;
    for(i=0;i<n;i++)a[i]=a[i]-O,a[i].cal();
    if(!n)return;
    sort(a,a+n,cmp);
    a[n]=a[0];
    for(i=0;i<n;i++)f[i]=P(a[i]*a[i+1]/a[i].len()/a[i+1].len(),a[i].len()/a[i+1].len());
    for(nxt[0]=j=-1,i=1;i<n;nxt[i++]=j){
      while(~j&&f[j+1]!=f[i])j=nxt[j];
      if(f[j+1]==f[i])j++;
    }
  }
}A,B;
void init(){
  scanf("%d",&l);
  for(i=0;i<l;i++)scanf("%lf%lf",&b[i].x,&b[i].y);
}
bool check(){
  if(A.n!=B.n||A.m!=B.m)return 0;
  if(!A.n)return 1;
  for(j=-1,k=0;k<2;k++)for(i=0;i<A.n;i++){
    while(~j&&B.f[j+1]!=A.f[i])j=nxt[j];
    if(B.f[j+1]==A.f[i]){
      j++;
      if(j==A.n-1)return 1;
    }
  }
  return 0;
}
int main(){
  init();
  A.init0();
  A.init();
  scanf("%d",&T);
  while(T--){
    init();
    B.init0();
    B.init();
    if(check()){puts("TAK");continue;}
    B.init1();
    B.init();
    puts(check()?"TAK":"NIE");
  }
  return 0;
}

  

时间: 2024-10-12 14:23:15

BZOJ1527 : [POI2005]Pun-point的相关文章

【BZOJ 1528】 1528: [POI2005]sam-Toy Cars (贪心+堆)

1528: [POI2005]sam-Toy Cars Description Jasio 是一个三岁的小男孩,他最喜欢玩玩具了,他有n 个不同的玩具,它们都被放在了很高的架子上所以Jasio 拿不到它们. 为了让他的房间有足够的空间,在任何时刻地板上都不会有超过k 个玩具. Jasio 在地板上玩玩具. Jasio'的妈妈则在房间里陪他的儿子. 当Jasio 想玩地板上的其他玩具时,他会自己去拿,如果他想玩的玩具在架子上,他的妈妈则会帮他去拿,当她拿玩具的时候,顺便也会将一个地板上的玩具放上架

[POI2005]Kos-Dicing|二分|最大流

1532: [POI2005]Kos-Dicing Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1222  Solved: 387[Submit][Status][Discuss] Description Dicing 是一个两人玩的游戏,这个游戏在Byteotia非常流行. 甚至人们专门成立了这个游戏的一个俱乐部. 俱乐部的人时常在一起玩这个游戏然后评选出玩得最好的人.现在有一个非常不走运的家伙,他想成为那个玩的最好的人,他现在知道了所有比赛的安

BZOJ1531: [POI2005]Bank notes

1531: [POI2005]Bank notes Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 229  Solved: 119[Submit][Status] Description Byteotian Bit Bank (BBB) 拥有一套先进的货币系统,这个系统一共有n种面值的硬币,面值分别为b1, b2,..., bn. 但是每种硬币有数量限制,现在我们想要凑出面值k求最少要用多少个硬币. Input 第一行一个数 n, 1 <= n <

[POI2005]ska Piggy banks|并查集|tarjan

1529: [POI2005]ska Piggy banks Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 973  Solved: 445[Submit][Status][Discuss] Description Byteazar 有 N 个小猪存钱罐. 每个存钱罐只能用钥匙打开或者砸开. Byteazar 已经把每个存钱罐的钥匙放到了某些存钱罐里. Byteazar 现在想买一台汽车于是要把所有的钱都取出来. 他想尽量少的打破存钱罐取出所有的钱,

BZOJ 1537: [POI2005]Aut- The Bus(dp + BIT)

对y坐标离散化, 然后按x坐标排序, dp. 一个点(x, y), 设到达这个点接到的最多乘客数为t, 那么t可以用来更新y'>=y的所有点.用树状数组维护最大值. --------------------------------------------------------------------------------- #include<bits/stdc++.h> using namespace std; const int maxn = 100009; int N; #def

PUN介绍(干货)

PUN介绍 入门 Photon Unity Networking(首字母缩写PUN)是一个Unity多人游戏插件包.它提供了身份验证选项.匹配,以及快速.可靠的通过我们的Photon后端实现的游戏内通信. PUN输出几乎所有Unity支持的平台,且有两种选项: 注意:对于Unity 5,两个PUN插件包都含相同的文件.你可以买PUN+ 来获得60个月的100 CCU,但客户端上仍使用PUN Free. PUN.PUN+和UNet的对比 详见文章Photon Unity Networking (P

bzoj1528[POI2005]sam-Toy Cars*&amp;&amp;bzoj1826[JSOI2010]缓存交换

bzoj1528[POI2005]sam-Toy Cars bzoj1826[JSOI2010]缓存交换 题意: Jasio有n个不同的玩具,它们都被放在了很高的架子上,地板上不会有超过k个玩具.当Jasio想玩地板上的其他玩具时,他会自己去拿,如果他想玩的玩具在架子上,他的妈妈则会帮他去拿,当她拿玩具的时候,顺便也会将一个地板上的玩具放上架子使得地板上有足够的空间.他的妈妈知道孩子的p个请求,求通过决定每次换玩具时换下哪个所能使他妈妈架子上拿玩具的次数的最小值.k≤100000,p≤50000

Bzoj 1537: [POI2005]Aut- The Bus 题解 [由暴力到正解]

1537: [POI2005]Aut- The Bus Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 387  Solved: 264[Submit][Status][Discuss] Description Byte City 的街道形成了一个标准的棋盘网络 – 他们要么是北南走向要么就是西东走向. 北南走向的路口从 1 到 n编号, 西东走向的路从1 到 m编号. 每个路口用两个数(i, j) 表示(1 <= i <= n, 1 <= j

BZOJ 1531: [POI2005]Bank notes( 背包 )

多重背包... ---------------------------------------------------------------------------- #include<bits/stdc++.h> #define rep(i, n) for(int i = 0; i < n; i++) #define clr(x, c) memset(x, c, sizeof(x)) using namespace std; const int maxn = 209, maxk =