HDU 5334 Virtual Participation(2015多校第四场)

 
Problem Description
 
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he asks rikka to
have some practice on codeforces. Then she opens the problem B:

Given an integer K, she needs to come up with an sequence of integers A satisfying that the
number of different continuous subsequence of A is equal to k.

Two continuous subsequences a, b are different if and only if one of the following conditions
is satisfied:

1. The length of a is not equal to the length of b.

2. There is at least one t that atbt, where at means the t-th element of a and bt means the 
    t-th element of b.

Unfortunately, it is too difficult for Rikka. Can you help her?
 
Input
 
There are at most 20 testcases,each testcase only contains a single integer K (1K109)
 
Output
 
For each testcase print two lines.

The first line contains one integers n (nmin(K,105)).

The second line contains n space-separated integer Ai (1Ain) - the sequence you find.
 
Sample Input
 
10
 
Sample Output
 
4
1 2 3 4
 
 
题意:给一个整数k,输出一个长度为n的数列。要求这个数列的所有不为空且不相同的连续子序列的个数为k。
 
 
题解:当数列元素都为1时,数列子序列个数为k。所以当k小于等于105时,可以直接输出k个1。
 
当k大于105时,对于一个1到n的数列,该数列的子序列个数m为n(n+1)/2。如果我们将某个不与1相邻的数替换为1, 那么其m值就会减1;如果是从2的位置开始连续将x个数变为1,其m值减少x(x+1)/2。比如 1 2 3 4 5 6 7 8将3个数变为1后为 1 1 1 1 5 6 4 8,m值减少了6。
 
对于给定的k,我们可以先找到一个子序列个数大于等于k且最接近的数列n,则这个数列的长度就是我们所要求的数列的长度。当m>k时,求出连续1的个数和不连续1的个数, 将相应位置的数替换成1。
 
 
 
 1 #include <cstdio>
 2 #include <cmath>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 int pos[45000];  //存储数列的子序列的个数
 8 void F()
 9 {
10     for (int i=1; i<44730; i++)
11         pos[i] = (i * i + i) / 2;
12 }
13 int main()
14 {
15     F();
16     int k;
17     while (~scanf("%d", &k)){
18         if (k <= 100000){
19             printf("%d
", k);
20             for (int i=1; i<k; i++)
21                 printf("1 ");
22             printf("1
");
23         }
24         else{
25             int x;
26             //找到子序列个数大于k的数列n
27             for (int i=1; i<44730; i++)
28                 if (pos[i] >= k && pos[i-1] < k){
29                     x = i;
30                     break;
31                 }
32             //数列n中不与1相邻元素所要替换成1的个数
33             int y = pos[x] - k;
34             printf("%d
", x);
35             int temp;
36             //找到连续1的个数
37             for (int i=1; i<44730; i++)
38                 if (pos[i] <= y && pos[i+1] > y){
39                     temp = i;
40                     break;
41                 }
42             printf("1");
43             for (int i=1; i<=temp; i++)
44                 printf(" 1");
45             //不与1相邻元素所要替换成1的个数
46             y = y - pos[temp];
47             int ans = 1;
48             for (int i=temp+2; i<=x; i++){
49                 ans++;
50                  if (ans % 2 && y > 0){
51                     printf(" 1");
52                     y--;
53                  }
54                  else
55                     printf(" %d", i);
56             }
57             printf("
");
58         }
59     }
60     return 0;
61 }
View Code
 
 
原文地址:https://www.cnblogs.com/hgfblog/p/4692411.html