【10.26 校内普及组】圆盘 题解
题目
解题思路
先将每一个圆盘取的点排序求差
然后再复制一遍放在后面
求出每个圆盘的最小表示
然后一一比较
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct hhx{
int h[1020];
}a[520];
int n,m,p,k,x[520],ans,next[520],f[520];
int main()
{
scanf("%d%d%d",&n,&m,&p);
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
scanf("%d",&x[j]);
sort(x+1,x+m+1); //排序
for (int j=2;j<=m;j++)
{
a[i].h[j-1]=x[j]-x[j-1];
a[i].h[j+m-1]=a[i].h[j-1];
} //求差
a[i].h[m]=x[1]+p-x[m];
a[i].h[m+m]=a[i].h[m]; //第一个和最后一个的差
int w=1,y=2,k=0;
while (w<=2*m&&y<=2*m)
{
k=0;
while (a[i].h[w+k]==a[i].h[y+k]&&k<=2*m)
k++;
if(k==2*m) break;
if (a[i].h[w+k]<a[i].h[y+k])
{
w+=k+1;
if (w==y) w++;
}
else
{
y+=k+1;
if (w==y) y++;
}
}
f[i]=min(w,y); //求出最小表示
for (int j=1;j<i;j++) //和别的圆盘比较
{
int p=1;
for (int q=1;q<=m;q++)
if (a[i].h[f[i]+q-1]!=a[j].h[f[j]+q-1])
{
p=0;
break;
}
if (p) ans++; //完全重合,答案+1
}
}
printf("%d",ans);
return 0;
}