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;
}


posted @ 2017-01-25 23:38  Lawliet__zmz  阅读(227)  评论(0编辑  收藏  举报