赛场上憾失金牌的题目
理论上最多旋转0/90/180/270这4个状态
我写了枚举1点转到哪里,2点转到哪里,然后通过旋转角度求
把eps设大一点精度问题就可以解决了
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
typedef long long LL;
const int mod = 1e9+7;
#define CLR(a,b) memset(a,b,sizeof(a))
const double eps=1e-4;
const double pi=acos(-1.0);
#define next(i) ((i+1)%n)
inline int cmp(double x) { //≈–∂œ ˝µƒ∑˚∫≈
return x<-eps?-1:x>eps?1:0;
}
inline double sqr(double x) { //º∆À„ ˝µƒ∆Ω∑Ω
return x*x;
}
struct point { //µ„¿‡
double x,y;
point() {}
point(double a,double b):x(a),y(b) {}
void input() {
scanf("%lf%lf",&x,&y);
}
friend point operator+(const point &a,const point &b) {
return point(a.x+b.x,a.y+b.y);
}
friend point operator-(const point &a,const point &b) {
return point(a.x-b.x,a.y-b.y);
}
friend bool operator==(const point &a,const point &b) {
return cmp(a.x-b.x)==0&&cmp(a.y-b.y)==0;
}
friend point operator*(const point &a,const double b) {
return point(a.x*b,a.y*b);
}
friend point operator*(const double a,const point &b) {
return point(a*b.x,a*b.y);
}
friend point operator/(const point &a,const double b) {
return point(a.x/b,a.y/b);
}
double norm() {
return sqrt(sqr(x)+sqr(y));
}
};
double det(const point &a,const point &b) { //º∆À„œÚ¡ø≤ʪ˝
return a.x*b.y-a.y*b.x;
}
double dot(const point &a,const point &b) { //º∆À„œÚ¡øµ„ª˝
return a.x*b.x+a.y*b.y;
}
double dist(const point &a,const point &b) { //º∆À„¡Ωµ„懿Î
return (a-b).norm();
}
point rotate_point(const point &p,double A) { //º∆À„œÚ¡øp»∆ƒÊ ±’Ζ˝◊™Aª°∂»µ√µΩµƒœÚ¡ø
return point(p.x*cos(A)-p.y*sin(A),p.x*sin(A)+p.y*cos(A));
}
LL fpow(int n ,int k){
LL ans = 1,base = n;
while(k){
if(k & 1)ans = ans * base % mod;
base = base * base % mod;
k >>= 1;
}
return ans;
}
const int N = 205;
int n,m,c,idx[N];;
point p[N],np[N];
bool go[N][N],vis[N];
int check()
{
for(int i =1 ;i <= n ; i++){
for(int j = 1; j <= n ; j++){
if(go[i][j] && !go[idx[i]][idx[j]])return -1;
}
}
CLR(vis, 0);
int cnt = 0;
for(int i = 1 ;i <= n ; i++){
if(vis[i])continue;
cnt ++;
int nxt = idx[i];
int start = i;
vis[nxt] = 1;
while(idx[nxt] != start){
nxt = idx[nxt];
vis[nxt] = 1;
}
}
return fpow(c,cnt);
}
void solve()
{
LL ans = 0;
int G = 0;
for(int i = 1 ;i <= n ; i ++){
for(int j = 1 ; j <= n ; j++){
if(i == j)continue;
if((p[j]-p[i]).norm() != (p[2]-p[1]).norm())continue;
double phi = asin(det(p[2]-p[1],p[j]-p[i])/(p[2]-p[1]).norm()/(p[j]-p[i]).norm());
if(phi == 0){
phi = acos(dot(p[2]-p[1],p[j]-p[i])/(p[2]-p[1]).norm()/(p[j]-p[i]).norm());
}
np[1] = p[i];
np[2] = p[j];
for(int k = 3; k <= n ; k++){
np[k] = rotate_point((p[k]-p[1]),phi) + p[i];
}
bool ok = 1;
CLR(idx,-1);
idx[1] = i;
idx[2] = j;
for(int k = 3 ;k <= n ; k ++){
bool fid = 0;
for(int l = 1 ; l <= n ; l ++){
if(np[k] == p[l]){
idx[k] = l;
fid = 1;
break;
}
}
if(!fid)ok = 0;
}
if(!ok)continue;
int ret = check();
if(ret == -1)continue;
else {(ans += ret) %= mod;G++;}
}
}
printf("%lld\n",ans*fpow(G,mod-2)%mod);
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&m,&c);
for(int i = 1; i <= n ; i++){
p[i].input();
}
for(int i = n+1 ; i<= 2 * n ;i ++){
p[i] = p[i-n];
}
CLR(go,0);
for(int i = 0 ; i < m ; i ++){
int a,b;
scanf("%d%d",&a,&b);
go[a][b] = go[b][a] = 1;
}
solve();
}
return 0;
}