JAVA大数_棋盘覆盖
第一道:
传送门: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.csdn.net/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; }