HDU 5047 Sawtooth 找规律+拆分乘
Sawtooth
Think about a plane:
● One straight line can divide a plane into two regions.
● Two lines can divide a plane into at most four regions.
● Three lines can divide a plane into at most seven regions.
● And so on...
Now we have some figure constructed with two parallel rays in the same direction, joined by two straight segments. It looks like a character “M”. You are given N such “M”s. What is the maximum number of regions that these “M”s can divide a plane ?
● One straight line can divide a plane into two regions.
● Two lines can divide a plane into at most four regions.
● Three lines can divide a plane into at most seven regions.
● And so on...
Now we have some figure constructed with two parallel rays in the same direction, joined by two straight segments. It looks like a character “M”. You are given N such “M”s. What is the maximum number of regions that these “M”s can divide a plane ?
InputThe first line of the input is T (1 ≤ T ≤ 100000), which stands for the number of test cases you need to solve.
Each case contains one single non-negative integer, indicating number of “M”s. (0 ≤ N ≤ 10 12)OutputFor each test case, print a line “Case #t: ”(without quotes, t means the index of the test case) at the beginning. Then an integer that is the maximum number of regions N the “M” figures can divide.Sample Input
2 1 2Sample Output
Case #1: 2 Case #2: 19
题意:问用"M"形的线条去切割一个平面,问当有n个"M"时能把平面切割成几份?
用1条直线切割平面可以把平面分成2份
用2条直线切割平面可以把平面分成4份
用3条直线切割平面可以把平面分成7份
用n条直线切割平面可以把平面分成2+2+3+4+....+n份
假设"M"的线条可以无限延长成直线,那么一个M相当于4条直线,但是考虑到"M"实际上并没有延长成直线,那么一个"M"的切割份数一定小于4条直线的切割分数,
猜想二者可能满足某种关系。
直线:
n=4时,ans=11
n=8时,ans=37
“M”:
n=1时,ans=2
n=2时,ans=19
发现
11-9=2
37-2*9=19
设“M”个数为n,那么有4n*(4n+1)/2+1-9n ---> n*(8n-7)+1
直接输出答案会爆ll。
可以用JAVA或者高精度算法。
这里用的是拆分乘。
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll mod=1e9; int main() { //freopen("input.txt","r",stdin); ll T,kase=1; scanf("%lld",&T); while(T--) { ll n; scanf("%lld",&n); ll a0=(8*n-7)%mod; ll a1=(8*n-7)/mod; ll b0=n%mod; ll b1=n/mod; ll num0=(a0*b0+1); ll num1=(b0*a1+b1*a0+num0/mod); ll num2=(a1*b1+num1/mod); num0%=mod; num1%=mod; printf("Case #%lld: ",kase++); if(num2) printf("%lld%09lld%09lld\n",num2,num1,num0); else if(num1) printf("%lld%09lld\n",num1,num0); else printf("%lld\n",num0); } return 0; }