One Chance To Be The God Of Chrysanthemum

One Chance To Be The God Of Chrysanthemum
Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 59   Accepted Submission(s) : 3
Font: Times New Roman | Verdana | Georgia 
Font Size: ← →

Problem Description

  Last week xysDavid had gone for an interview. The interviewer asked him a funny question. Here is it.
  Given a number n, your mission is to find a set, that every number between 1 and n (inclusive) can be the sum of some elements in this set.
  xysDavid seckilled it soon after reading the statement. If you can solve the problem too, xysDavid will accept you to be his apprentice, who can get the honorary title 'the god of chrysanthemum'.
  Can you finish it?

Input

  There is a number T (1<=T<=50) in the first line, indicating the number of test cases.
  There is a number n in each line. (1<=n<=10^18);

Output

  You should output "Case #D:" first, which "D" means the index of the test case.
  Then output all the numbers in the set in one line in increasing order. Use one space to separate two numbers. Please note that no more spaces in the end of a line.
   If there are multiple answers, output the one with smallest number of elements. If it is still a tie, output the one with the smallest lexicographical order.
  The comparison between two sequences uses lexicographical ordering: first, the first two numbers are compared, and if they differ this determines the outcome of the comparison; if they are equal, the next two numbers are compared, and so on, until either sequence is exhausted. If all numbers of two sequences compare equal, the sequences are considered equal. If one sequence is an initial subsequence of the other, the shorted sequence is considered the smaller one.

Sample Input

2
1
3

Sample Output

Case #1:
1
Case #2:
1 2

Source

华南师范大学2012年ACM程序设计竞赛(初赛+决赛无尽版)

 

二分的思想

题意是:得到一个集合,使1到n都能用该集合内的某些元素和来表示。如果求得的集合有多个,输出元素个数最少的一个,如果还是有,输出字典序最小的集合。

 

#include<iostream>
#include<cstdio>
#include<set>
using namespace std;
#define LL __int64

set<LL> q;
set<LL>::iterator it;

LL solve(LL n) 
{
	if(n==1)
	{
		q.insert(1);
		return 1;
	}
	else
	{
		LL a=solve(n>>1);//a以下的数都能表示 
		LL b=n-a;//剩下的数b 
		while(q.count(b))//找到不重复的最小值 
		{
			b++;
		}
		q.insert(b);
		return b+a;//返回a+b以下都能表示 
	}
}

int main()
{
	int t;
	int cnt=1;
	cin>>t;
	while(t--)
	{
		LL n;
		cin>>n;
		q.clear();
		printf("Case #%d:\n",cnt++);
		solve(n);
		
		it=q.begin();
		printf("%I64d",*it);
		for(it++;it!=q.end();it++)
			printf(" %I64d",*it);
		cout<<endl;
	}
	return 0;
} 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值