Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu

[]   [Go Back]   [Status]  

Description

 

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
-           1 ≤ n < 1000000000

 

Sample Input

Output for Sample Input

4
1
10
100
1000

15
178
30
8141

 

好恶心的矩阵构造啊!

  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\n");
108             continue;
109         }
110         else if(m==2)
111         {
112             printf("69\n");
113             continue;
114         }
115         printf("%d\n",solve(m));
116     }
117 }
View Code

 

 

posted on 2014-04-19 09:18  ERKE  阅读(300)  评论(0编辑  收藏  举报