HDU 5080 polya定理
来源:互联网 发布:中国农业大学网络管理 编辑:程序博客网 时间:2024/05/29 19:40
分析: 因为坐标只有整数,所以只能是转90度 或者180 或者 不转。
根据polya定理,我们可以求出所有的方案数, 前提是证明出这个玩具是每转90度相同的还是180度还是不转。
如何证明这个玩具转的角度。我用了暴力枚举的方法,因为n<=50,O(n^4)算法足够了,是这样的,枚举任意两个点的中点。
如果这个中点是所有点对的中点,那么这个中点就是旋转点。然后每次逆时针旋转90度,看和原来的边和点是否匹配。
然后根据旋转的角度来计算等价类的个数,具体如何计算等价类,请百度polya定理。参考AC代码:
#include<cstdio>typedef long long LL;const int MOD = 1000000007;struct Point{ double x,y; Point(double x=0, double y=0){this->x=x;this->y=y;}}p[55],p1[55];bool operator==(const Point &a, const Point &b){ return a.x == b.x && a.y == b.y;}struct Line{ Point a,b;}l[1555],l1[1555];bool operator==(const Line &l1, const Line &l2){ return l1.a == l2.a && l1.b == l2.b || l1.a == l2.b && l1.b == l2.a;}int n, m, c;double x,y;bool find_mid(){ bool flag = false; for(int i = 1; i <= n; i++){ for(int j = i + 1; j <= n; j++){ x = p[i].x + p[j].x; y = p[i].y + p[j].y; flag = true; for(int k = 1; k <= n; k++){ Point t(x-p[k].x, y-p[k].y); int o; for(o = 1; o <= n; o++){ if(p[o] == t) break; } if(o > n){flag = false;break;} } if(flag) return true; } } return false;}Point rotate(Point a){ return Point(a.y+(-y+x)/2, -a.x+(x+y)/2);}bool rever(Point *pfrom, Line *lfrom, Point *pto, Line *lto){ for(int i = 1; i <= n; i++){ pto[i] = rotate(pfrom[i]); } for(int i = 1; i <= m; i++){ lto[i].a = rotate(lfrom[i].a); lto[i].b = rotate(lfrom[i].b); } bool flag = true; for(int i = 1; i <= n; i++){ int j; for(j = 1; j <= n; j++){ if(pto[i] == p[j]) break; } if(j > n){flag = false; break;} } if(flag){ for(int i = 1; i <= m; i++){ int j; for(j = 1; j <= m; j++){ if(lto[i] == l[j]){ break; } } if(j > m){flag = false; break;} } } return flag;}int gcd(int a, int b){ return b == 0 ? a : gcd(b, a%b);}LL pow_mod(LL base, int exp){ LL ret = 1; while(exp){ if(exp&1) ret = ret * base % MOD; base = base * base % MOD; exp >>= 1; } return ret;}LL rev(int d){ return pow_mod(d, MOD-2);}LL cal(int d){ LL r = (n % d == 0 ? 1 : c); n /= d; LL ans = 0; for(int i = 0; i < d; i++){ ans = (ans + pow_mod(c, n * gcd(i, d))) % MOD; } ans = ans * rev(d) % MOD; return ans * r % MOD;}int main(){ // freopen("1.txt","r",stdin); int T;scanf("%d", &T); while(T--){ scanf("%d%d%d", &n, &m, &c); for(int i = 1; i <= n; i++){ scanf("%lf%lf", &p[i].x, &p[i].y); } int a,b; for(int i = 1; i <= m; i++){ scanf("%d%d", &a, &b); l[i].a = p[a]; l[i].b = p[b]; } int d; if(find_mid()){ if(rever(p,l,p1,l1)){ d = 4; }else if(rever(p1,l1,p1,l1)){ d = 2; }else d = 1; }else d = 1; printf("%I64d\n", cal(d)); } return 0;}<strong></strong>
0 0
- HDU 5080 polya定理
- HDU 5080 Colorful Toy (polya定理)
- hdu 4259 polya定理
- hdu 3923 Invoker polya定理
- HDU 3923 Invoker (polya定理)
- HDU 3547 DIY Cube 数论- Polya定理
- HDU 1812 - Count the Tetris【Polya定理】
- HDU 1817 - Necklace of Beads【Polya定理】
- polya定理
- polya定理
- polya定理
- Polya定理
- Polya定理
- polya 定理
- HDU 3923 Invoker (polya 定理+逆元)
- HDU 4633 Who's Aunt Zhang (Polya定理)
- HDU 1812 Count the Tetris (polya定理+高精度)
- poj 1286 poj 2409 hdu 1812 polya定理 组合数学
- is_file、is_dir和file_exists用途和效率比较
- Linux下图形界面调试工具kdbg安装及测试
- 提交表单 form submit 不跳转实现
- 【重读设计模式】解释器模式
- ubuntu 无线网卡安装
- HDU 5080 polya定理
- 乘法口诀
- java的File测试代码
- 1234 开门人和关门人
- Java中的多线程
- 求区间[a,b]之间的大数据的回文数个数解题报告
- linux中的信号量机制
- 用队列打印杨辉三角
- smarty学习浅析与笔记