Time Limit: 3000MS | Memory Limit: Unknown | 64bit IO Format: %lld & %llu |
Description
I I U P C 2 0 0 6 |
|
Problem H: How many Knight Placing? |
|
Input: standard input Output: standard output |
|
|
|
You are given a 6*n chessboard. Yes it is not a regular chessboard. The number of columns in this chessboard is variable. In each of the columns you have to place exactly 2 knights. So you have to place total 2*n knights. You have to count the number of valid placing of these 2*n knight. A placing is invalid if any of the 2 knights attack each other. Those who are not familiar with knight moves “A knight in cell(x,y) attacks the knights in the cell(x±2,y±1) and cell(x±1,y±2)”. |
|
Input |
|
The first line of the input contains a single integer T indicating the number of test cases. Each test case contains a single integer n. |
|
Output |
|
For each test case output an integer the number of valid placing. The integer may be very large. So just output the result%10007. |
|
Constraints |
|
- T ≤ 15 |
|
Sample Input |
Output for Sample Input |
4 |
15 |
好恶心的矩阵构造啊!
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 using namespace std; 5 #define mod 10007 6 typedef struct point 7 { 8 int x,y; 9 } point; 10 typedef struct mar 11 { 12 int a[70][70]; 13 } mar; 14 mar ri,anss,riri; 15 point p[70]; 16 int a[20]; 17 int check(int t) 18 { 19 int sum=0; 20 while(t) 21 { 22 if(t&1)sum++; 23 t>>=1; 24 } 25 return sum==2; 26 } 27 bool fun(int x,int y) 28 { 29 if((x<<2)&y||(y<<2)&x)return 0; 30 return 1; 31 } 32 bool fun1(int x,int y,int z) 33 { 34 if(!fun(x,y)||!fun(y,z))return 0; 35 if((x<<1)&z||(z<<1)&x)return 0; 36 return 1; 37 } 38 mar mul(mar x,mar y) 39 { 40 mar z; 41 memset(z.a,0,sizeof(z.a)); 42 int i,j,k; 43 for(k=0; k<69; k++) 44 for(i=0; i<69; i++) 45 if(x.a[i][k]) 46 for(j=0; j<69; j++) 47 z.a[i][j]+=x.a[i][k]*y.a[k][j]%mod,z.a[i][j]%=mod; 48 return z; 49 } 50 void init() 51 { 52 int tt=(1<<6)-1,nu=0,i,j; 53 while(tt) 54 { 55 if(check(tt)) 56 a[nu++]=tt; 57 tt--; 58 } 59 nu=0; 60 for(i=0; i<15; i++) 61 for(j=0; j<15; j++) 62 if(fun(a[i],a[j])) 63 p[nu].x=a[i],p[nu++].y=a[j]; 64 memset(ri.a,0,sizeof(ri.a)); 65 for(i=0; i<69; i++) 66 { 67 for(j=0; j<69; j++) 68 { 69 if(p[i].y==p[j].x) 70 { 71 if(fun1(p[i].x,p[i].y,p[j].y)) 72 ri.a[i][j]=1; 73 } 74 } 75 } 76 } 77 int solve(int m) 78 { 79 int i,j,ans=0; 80 memset(anss.a,0,sizeof(anss.a)); 81 memset(riri.a,0,sizeof(riri.a)); 82 for(i=0; i<69; i++)anss.a[i][i]=1; 83 for(i=0; i<69; i++) 84 for(j=0; j<69; j++)riri.a[i][j]=ri.a[i][j]; 85 m-=2; 86 while(m) 87 { 88 if(m&1) 89 anss=mul(anss,riri); 90 riri=mul(riri,riri); 91 m>>=1; 92 } 93 for(i=0; i<69; i++) 94 for(j=0; j<69; j++)ans+=anss.a[i][j],ans%=mod; 95 return ans; 96 } 97 int main() 98 { 99 init(); 100 int t,m; 101 scanf("%d",&t); 102 while(t--) 103 { 104 scanf("%d",&m); 105 if(m==1) 106 { 107 printf("15 "); 108 continue; 109 } 110 else if(m==2) 111 { 112 printf("69 "); 113 continue; 114 } 115 printf("%d ",solve(m)); 116 } 117 }