ZOJ3768Continuous Login (等差求和公式+二分)
2014-04-07 16:44
267 查看
Pierre is recently obsessed with an online game. To encourage users to log in, this game will give users a continuous login reward. The mechanism of continuous login reward is as follows: If you have not logged in on a certain day, the reward of that day
is 0, otherwise the reward is the previous day's plus 1.
On the other hand, Pierre is very fond of the number N. He wants to get exactly
N points reward with the least possible interruption of continuous login.
There is one integer N (1 <= N <= 123456789).
This problem is special judged so any correct answer will be accepted.
19 = (1 + 2 + 3) + (1 + 2 + 3 + 4) + (1 + 2)
6 = (1 + 2 + 3)
9 = (1 + 2) + (1 + 2 + 3)
Some problem has a simple, fast and correct solution.
解题:通过列出组和方式,得知组和的组数最多只有3个,输出原则是:先组数最小,组数相等的每组的数字尽量平分。
首先:用求和分式列出只要一组就能组成的数 。 再查找时,先查只有一组的,如果没有,再查两组的,两组都是建立在一组基础之上。如果两组不能组成就用三组来构成输入的数M。
is 0, otherwise the reward is the previous day's plus 1.
On the other hand, Pierre is very fond of the number N. He wants to get exactly
N points reward with the least possible interruption of continuous login.
Input
There are multiple test cases. The first line of input is an integer T indicates the number of test cases. For each test case:There is one integer N (1 <= N <= 123456789).
Output
For each test case, output the days of continuous login, separated by a space.This problem is special judged so any correct answer will be accepted.
Sample Input
4 20 19 6 9
Sample Output
4 4 3 4 2 3 2 3
Hint
20 = (1 + 2 + 3 + 4) + (1 + 2 + 3 + 4)19 = (1 + 2 + 3) + (1 + 2 + 3 + 4) + (1 + 2)
6 = (1 + 2 + 3)
9 = (1 + 2) + (1 + 2 + 3)
Some problem has a simple, fast and correct solution.
解题:通过列出组和方式,得知组和的组数最多只有3个,输出原则是:先组数最小,组数相等的每组的数字尽量平分。
首先:用求和分式列出只要一组就能组成的数 。 再查找时,先查只有一组的,如果没有,再查两组的,两组都是建立在一组基础之上。如果两组不能组成就用三组来构成输入的数M。
#include<iostream> #include<stdio.h> #include<algorithm> using namespace std; #define N 123456789 int ans[20000],n; int find(int M) { int l,r,m; l=1; r=n; while(l<=r) { m=(l+r)/2; if(M==ans[m])return m; if(M>ans[m])l=m+1; else r=m-1; } if(ans[m]>M)m--; return m; } int main() { int k[3],M,t,a,b,c,flog; for(n=1;n*(n+1)/2<=N;n++) ans =n*(n+1)/2; n=n-1; scanf("%d",&t); while(t--) { scanf("%d",&M); k[0]=find(M); if(ans[k[0]]==M) printf("%d\n",k[0]); else{ a=M/2; b=M-a; flog=0; k[1]=find(b); if(ans[k[1]]<b)k[1]++; for(;ans[k[1]]<M&&k[1]<=n;k[1]++) { k[0]=find(M-ans[k[1]]); if(ans[k[0]]+ans[k[1]]==M) { printf("%d %d\n",k[0],k[1]); flog=1; break; } } if(flog==0) { int tem; a=M/3; k[0]=find(a); for(;k[0]>0&&flog==0;k[0]--) for(k[1]=k[0];ans[k[0]]+ans[k[1]]<M&&k[1]<=n;k[1]++) { c=M-ans[k[0]]-ans[k[1]]; k[2]=find(c); if(ans[k[0]]+ans[k[1]]+ans[k[2]]==M) { if(k[2]>k[0]){tem=k[2]; k[2]=k[0]; k[0]=tem; } if(k[2]>k[1]){tem=k[2]; k[2]=k[1]; k[1]=tem; } if(k[0]>k[1]){tem=k[0]; k[0]=k[1]; k[1]=tem; } printf("%d %d %d\n",k[0],k[1],k[2]); flog=1; break; } } } } } }
相关文章推荐
- 等差等比数例求和公式
- 等差求和-公式+大数long long(蓝桥)
- hdu 1597 find the nth digit(等差求和+二分)
- uvalive2222(等差序列前n项求和)
- LA 4642 马尔法蒂问题 (二分或推公式)
- 求和(数学公式推导、取余运算)
- Execl中进行时间相加,对时间求和的公式:
- csuoj X - Rectangles (公式推导或者二分)
- 关于前n个平方数求和公式的无字证明
- HDU 1588 Gauss Fibonacci 斐波那契矩阵+等比矩阵二分求和
- 如何在office2010中的EXCEL表格使用求和公式
- zoj 2614 Bridge 积分 (公式 和 simpson ) + 二分
- 等差等比数列求和公式,排列组合公式, 二项式求根公式
- 求和公式推译与C语言测试
- 组合数有关的公式及常用求和
- zzuli oj 1919(序列分段求和)(二分)
- Codeforces Round #202 (Div. 1) A. Mafia 推公式 + 二分答案
- 蓝桥杯2014年以前JAVA历年真题及答案整理——求和公式
- 等比数列二分求和(首项为0次项与1次项的方法)
- poj1845(唯一分解定理,等比数列求和,约数个数公式)