2015-2016ACM-ICPC NEER northern-subregional-contest D Distribution in Metagonia 模拟构造

来源:互联网 发布:犀牛软件安装包 编辑:程序博客网 时间:2024/06/02 15:25

题目描述:

There are one hundred noble families in the country of Metagonia, and each year some of these families receive several ritual cubes from the Seer of the One. The One has several rules about cube distribution:
if a family receives at least one cube, every prime divisor of the number of cubes received should be either 2 or 3, moreover if one family receives a > 0 cubes and another family in the same year receives b > 0 cubes then a should not be divisible by b and vice versa.
You are the Seer of the One. You know in advance how many cubes would be available for distribution for the next t years. You want to find any valid distribution of cubes for each of these years. Each year you have to distribute all cubes available for that year.
Input
The first line of input file contains a single integer t — the number of years to come (1 ≤ t ≤ 1000).
Each of the following t lines contains a single integer ni — the number of cubes to distribute in i-th year (1 ≤ ni ≤ 1018).
Output
For each year i output two lines. The first line should contain mi — the number of families that would receive at least one cube in i-th year (1 ≤ mi ≤ 100). The second line should contain mi integers — the number of cubes received by each family. The sum of these numbers should be equal to ni。
.
Example

input

412310

output

11121324 6

题目分析:

给定一个数n,将这个数分解为若干个数之和。这若干个数都满足2^p*3^q形式,并且这些数之间不存在整除关系。因为有多种构造可能,你只要输出满足约束条件的答案即可。

因为这些数要求是2^p*3^q形式,所以我们先将n中的2因子个数和3因子个数提取出来,这样n就变成了一个较小的数。这个较小的数若是1,则说明这个数没有2和3以外的因子,就可以直接由它本身构成;其它情况,首先将其中一部分能够组成3的q次方的答案拿出来,较小的数减掉这个数之后上方的操作。
为什么不先把2的p次方提取出来呢?原因就是很有可能造成被分解的数之间存在整除关系。比如5,我们先将其中能分解的3取出来,就成为2和3,若将5分解成1和4,就是错误的,而且10也会变成2和8,而不是正确的4和6。

代码如下:

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>typedef long long LL;using namespace std;int T;LL n,m;LL ans[1010];void fun(LL n,LL x){    while(n%2==0)    {        n/=2;        x*=2;    }    while(n%3==0)    {        n/=3;        x*=3;    }    if (n==1)    {        m++;        ans[m]=x;    }    else    {        LL tmp=3;        while(tmp*3<n) tmp*=3;        m++;        ans[m]=tmp*x;        fun(n-tmp,x);    }}int main(){    //freopen("distribution.in","r",stdin);    //freopen("distribution.out","w",stdout);    scanf("%d",&T);    while(T--)    {        scanf("%I64d",&n);        m=0;        fun(n,1);        printf("%I64d\n",m);        for(int i=1; i<=m; i++)printf("%I64d ",ans[i]);        printf("\n");    }}
1 0
原创粉丝点击