nyoj 45 棋盘覆盖

来源:互联网 发布:知乎经济思想史 编辑:程序博客网 时间:2024/05/23 19:11

在一个2k×2k(1<=k<=100)的棋盘中恰有一方格被覆盖,如图1(k=2时),现用一缺角的2×2方格(图2为其中缺右下角的一个),去覆盖2k×2k未被覆盖过的方格,求需要类似图2方格总的个数s。如k=1时,s=1;k=2时,s=5

                                                                                    

 

 

 

 

 

 

 

 

 

图1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

                                              图2                    

 

 

 

 

 

 

输入
第一行m表示有m组测试数据;
每一组测试数据的第一行有一个整数数k;
输出
输出所需个数s;
样例输入
3
样例输出
21

分治求出填棋盘的规律。http://www.iamyoso.com/?p=393
具体就是fn = f(n-1) * 4 + 1; 或者 fn = (4^k -1 )/3
刚开始以为这题需要用后者,结果发现后者只能求到4^k,-1除以3这里不能求。
所以要用前者,把a0附为1, 不断乘4再+1, 注意这里的加1一定是加到a0上。
还有一点就是万进制。从前用10进制的浪费了ai,毕竟ai是个int类型,能表示的数不止0-9,所以用一个ai表示最大9999,然后输出的时候用d,如果直接输出%d,则每个ai的前导0都会被除掉。比如a1= 1005, a0 = 0033,应该输出10050033,就会变成100533.。。

#include
int main()
{
    int m, k, s, t, a[100],i, j, c;
    scanf("%d",&m);
    while(m--)
    {
       scanf("%d", &k);
       if(k == 1)
       {
          printf("1\n");
          continue;
       }
       a[0] = 1;
       t = 0; //t控制当前位数。
       for(i = 2 ; i <= k ; i++)
       {
           c =0;
           for(j = 0; j <= t ; j++)
           {
              s = a[j] * 4 + c;
              a[j] = s % 10000;
              c = s / 10000;
           }
           if(c !=0)
           {
              t++;
              a[t] = c;
           }
          a[0]++;
       }
       printf("%d", a[t]);
       for(i = t-1 ; i >= 0 ; i--)
          printf("d", a[i]); //如果不用04d那么每个ai的前导0都会被除掉。
       printf("\n");
    }
    return 0;
}

0 0