HDU - 5047 Sawtooth 找规律+推公式 (拆位计算)

题目链接

题意:

 给n条样子像“m”的折线,求它们能把二维平面分成的面最多是多少。



思路:


我们发现直线1条:2平面;2直线:4平面;3直线:7平面......因为第n条直线要与前面n-1条直线都相交,才能使分的平面最多,则添加第n条直线,平面增加n个;

所以公式是面F = 2 + 2 + 3 + ......+ n = (1+n)*n/2 + 1


因为题目的是“M”的折线,一个“M”有4条线将平面分成2块,4条直线将平面分成11块,它们之间相差9块; 当两个“M”,平面分成19块,8条直线,平面分成37块,相差18,

是9的倍数。平面每增加一个“M”,平面的相当于增加4条直线,但要减去9块
  给n个“M”,公式F = (1+4*n)*4*n/2+1-n*9 = n*(8*n-7)+1


因为n很大,肯定会爆ll了,这里就可以用到java大数过了.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.util.Scanner;


public class Main {
	  public static BufferedReader cin=new BufferedReader(new InputStreamReader(System.in));  
	  public static BufferedWriter cout=new BufferedWriter(new OutputStreamWriter(System.out)); 
	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		int _, ca = 1;
		_ = Integer.parseInt(cin.readLine());
		BigInteger x;
		BigInteger num2 = BigInteger.valueOf(2);
		BigInteger num8 = BigInteger.valueOf(8);
		BigInteger num7 = BigInteger.valueOf(7);
 		while(_-- != 0)
		{
			x = new BigInteger(cin.readLine());
			BigInteger ans = num8.multiply(x).multiply(x).subtract(num7.multiply(x)).add(BigInteger.ONE);
			System.out.println("Case #"+ ca + ": " + ans);
			ca++;
		}
	}
}


这里还有一个简单的技巧就是拆位成,这个方法在我们手写C++大数模板用到过,为了减少字符的位数,我们一位不采用十进制而是变成base 进制,(一般为10的整数倍)然后计算方法就是一样的了.

这个题目同理。

HDU - 5047 Sawtooth 找规律+推公式 (拆位计算)_第1张图片

#include

using namespace std;
const int mod = 1e9;
typedef long long ll;
ll n;
int main()
{
	int _;
	cin>>_;
	int ca = 1; 
	while(_--)
	{
		scanf("%lld",&n);
		ll t = 8 * n - 7;
		ll a0 = t  % mod;
		ll a1 = t / mod;
		ll b0 = n % mod;
		ll b1 = n / mod;
		ll num0 = a0*b0+1;
		ll num1 = a0*b1+a1*b0 + num0/mod;
		num0 %= mod;
		ll num2 = a1*b1+num1/mod;
		num1 %= mod;
		printf("Case #%d: ",ca++);
		if(num2) printf("%lld%09lld%09lld\n",num2,num1,num0);
		else if(num1) printf("%lld%09lld\n",num1,num0);
		else
		printf("%lld\n",num0);
	}
}





你可能感兴趣的:(java,acm技巧)