标签:ring 组合 string eof 测试 技术分享 width pre mil
题目描述
输入
输入包含多组测试数据。第一行包含一个正整数T,表示测试数据数目。每组测试数据包含一个整数n( 2<=N<=100),代表你需要求解的五角形圈中心的边数。
输出
对每一组测试数据,输出一行包含一个整数x,表示n五角形圈的生成树数目模2007之后的结果。
样例输入
1
2
样例输出
40
题解
矩阵树定理
看到无向图生成树个数,直接裸上矩阵树定理就好了(好像本题还有组合数学法)。
需要注意的是由于2007不是质数,因此需要辗转相除。
另外当n=2时由于某些特殊原因需要特判。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int mod = 2007; int a[410][410]; int main() { int T; scanf("%d" , &T); while(T -- ) { memset(a , 0 , sizeof(a)); int n , i , j , k , t , ans = 1 , d = 0; scanf("%d" , &n) , n <<= 2; if(n == 8) { puts("40"); continue; } for(i = 1 ; i <= n ; i ++ ) { a[i][(i + 1) % n] = a[(i + 1) % n][i] = -1 , a[i][i] = 2; if(i % 4 == 1) a[i][i] = 4 , a[i][(i + 4) % n] = a[(i + 4) % n][i] = -1; } for(i = 1 ; i < n ; i ++ ) { for(j = i ; j < n ; j ++ ) if(a[j][i]) break; if(j == n) continue; if(j != i) { d ^= 1; for(k = i ; k < n ; k ++ ) swap(a[i][k] , a[j][k]); } for(j = i + 1 ; j < n ; j ++ ) { while(a[j][i]) { t = a[j][i] / a[i][i]; for(k = i ; k < n ; k ++ ) a[j][k] = (a[j][k] - a[i][k] * t % mod + mod) % mod; if(!a[j][i]) break; d ^= 1; for(k = i ; k < n ; k ++ ) swap(a[i][k] , a[j][k]); } } } for(i = 1 ; i < n ; i ++ ) ans = ans * a[i][i] % mod; if(d) ans = (mod - ans) % mod; printf("%d\n" , ans); } return 0; }
标签:ring 组合 string eof 测试 技术分享 width pre mil
原文地址:http://www.cnblogs.com/GXZlegend/p/7355883.html