第一道:
传送门:NYOJ 45 棋盘覆盖
2^k*2^k=4^k,其实就是大数计算,-1后取3的倍数。问题本源出自《计算机算法设计与分析》的棋盘覆盖问题,原始解法是分治法,递推出公式f(k) = f(k - 1) * 4 + 1,f(1)=1,再化解下就是4^0 + 4^1 + 4^2 + ... + 4^(n-1)。有兴趣可以google原问题,附上一个不错的问题链接:棋盘覆盖
思路用大数加模拟就很简单了
Java版:
import java.math.BigInteger;
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int T = in.nextInt();
while(T-- >0) {
BigInteger a = new BigInteger("1");
int n = in.nextInt();
for(int i = 1; i<=n; i++) {
a = a.multiply(BigInteger.valueOf(4));
}
BigInteger ans = a.subtract(BigInteger.valueOf(1)).divide(BigInteger.valueOf(3));
System.out.println(ans);
}
}
}
C/C++:
#include <stdio.h>
#include <string.h>
int a[50];
int b[100];
void f()
{//大数*2
int i;
for(i = 0; i < 50; i++)
{
a[i] *= 2;
}
for(i = 0; i < 50 ; i++)
{
a[i + 1] += a[i] / 10;
a[i] %= 10;
}
}
void g()
{//大数减一,再除以三 、
b[0] - 1;
int i;
int k = 0, f = 0;
for(i = 99; i >= 0; i --)
{
if(b[i] != 0)
break;
}
/*
for(int j = 0; j < 100; j++)
printf("%d", b[j]);
printf("\n");
*/
for(; i >= 0 ; i--)
{
k = k * 10 + b[i];
if(k / 3 || f)
{
printf("%d", k / 3);
k %= 3;
f = 1;
}
}
if(f == 0)
printf("0");
printf("\n");
}
void f1()
{//大数的平方
int i, j;
for(i = 0; i < 50; i++)
{
for(j = 0; j < 50; j++)
{
b[i + j] += a[i] * a[j];
}
}
for(i = 0; i < 100; i++)
{
b[i + 1] += b[i] / 10;
b[i] %= 10;
}
}
int main (void)
{
int m;
scanf("%d", &m);
while(m --)
{
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
a[0] = 1;
int n, i;
scanf("%d", &n);
for(i = 0; i < n; i++)
f();
/*
for(i = 0; i < 50; i++)
printf("%d", a[i]);
printf("\n");
*/
f1();
g();
}
return 0;
}
网上其他人提出的万进制版本?
/*
* Author: illuz <iilluzen[at]gmail.com>
* Blog: http://blog.youkuaiyun.com/hcbbt
* File: 45.cpp
* Lauguage: C/C++
* Create Date: 2013-08-31 19:39:38
* Descripton: nyoj 45, cheesboard coverage, wan jin zhi
*/
#include <cstdio>
const int MAXN = 100;
int a[MAXN]; // 万进制,每位存4进制
int main() {
int n, m, c;
scanf("%d", &n);
while (n--) {
scanf("%d", &m);
if (m == 1) {
printf("1\n");
continue;
}
a[0] = 1;
int t = 0; // 已经用到第几位
for (int i = 1; i < m; i++) {
c = 0; // c为进位数
for (int j = 0; j <= t; j++) {
a[j] = a[j] * 4 + c;
c = a[j] / 10000;
a[j] %= 10000;
}
if (c != 0) {
t++;
a[t] = c;
}
a[0]++;
}
// 处理最后的进位,其实就是99999999这种情况,这里可以不用
// for (int j = 0; j <= t; j++) {
// c = a[j] / 10000;
// a[j] %= 10000;
// }
// if (c != 0) {
// t++;
// a[t] = c;
// }
printf("%d", a[t]);
for (int i = t - 1; i >= 0; i--)
printf("%04d", a[i]);
printf("\n");
}
return 0;
}