hdu5334 Virtual Participation 多校联合第四场

题意:给你一个数k,让你输出一个长度为n的数列, 该数列满足 不相等的子序列的个数和为k 关于不相等的定义题中有给出

思路:规律题  当k小于十万时,直接输出k个1,如果题目不要求n的范围 这道题可以都是输出k个1.。。。。

当k大于十万时首先对于一个1到n的数列 它对应的k值为n*(n+1)/2,然后打表 打到45000 就够了,然后再判断表中离k最近切大于k的数是多少,假设为n,我们想办法使其减去n即可办法如下:对于一个1到n的数列,如果我们将其某个数变为1(不与1相邻) 那么其k值就会减一,如果是从2的位置开始 连续将x个数变为1,比如 1 2 3 4 5 6 7 8将3个数变为1后为 1 1 1 1 5 6 4 8,其k值减少的个数为x(x+1)/2,先按连续变为1的方案来 如果不够 再接着不相邻的变为1的来 直到使其k值减成与输入的k相等然后输出该修改后的序列就行了

看不清楚的话就留言吧。。。。

代码:

#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <cstdio>
#include <string>
#include <bitset>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <map>
#include <set>
#define sss(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a) memset(a,0,sizeof(a))
#define ss(a,b) scanf("%d%d",&a,&b)
#define s(a) scanf("%d",&a)
#define INF 0x3f3f3f3f
#define w(a) while(a)
#define PI acos(-1.0)
#define LL long long
#define eps 10E-9
#define N 100000
#define mod 100000000
using namespace std;
void mys(int& res)
{
    int flag=0;
    char ch;
    while(!(((ch=getchar())>='0'&&ch<='9')||ch=='-'))
        if(ch==EOF)  res=INF;
    if(ch=='-')  flag=1;
    else if(ch>='0'&&ch<='9')  res=ch-'0';
    while((ch=getchar())>='0'&&ch<='9')  res=res*10+ch-'0';
    res=flag?-res:res;
}
void myp(int a)
{
    if(a>9)
        myp(a/10);
    putchar(a%10+'0');
}
/*************************THE END OF TEMPLATE************************/
int arr[N] = {0};
void init(){
    for(int i = 1; i<45000; i++){
        arr[i] = i*(i-1)/2 + i;
    }
}
int getR(int x){
    for(int i=1; i<45000; i++){
        if(arr[i] >= x) return i;
   }
}
int getL(int x){
    for(int i=1; i<45000; i++){
        if(arr[i] <= x && arr[i+1] >x) return i;
    }
}
int main()
{
    int k, i;
    init();
    w(~s(k)){
        int r;
        if(k <= 100000){
            cout<<k<<endl;
            for(int i=1; i<k; i++) cout<<"1 ";
            cout<<"1"<<endl;
        }
        else{
            r = getR(k);
            cout<<r<<endl;
            if(arr[r] == k){
                    for(i=1; i<r; i++) cout<<i<<" ";
                    cout<<i<<endl;
            }
            else{
                int cnt = arr[r] - k;
                int p = getL(cnt);
                int ans = cnt - arr[p];
                cout<<"1 ";
                for(i=2; i<=p+1; i++) cout<<"1 ";
                for(; i<r; i++){
                    if((i-p-1)%2==0 && ans>0){
                        cout<<"1 ";
                        ans--;
                    }
                    else cout<<i<<" ";
                }
                cout<<i<<endl;
            }
        }
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章