zoukankan      html  css  js  c++  java
  • 序列(seq)

    序列(seq)

    题目描述

    给定 N,A,BN,A,B,构造一个长度为 NN 的排列,使得:

    排列长度为 N;

    最长上升子序列长度为 A;

    最长下降子序列长度为 B。

    我们有 SPJ,有解任意给出一组,否则说明无解。

    输入

    第一行一个整数 TT (1≤T≤101≤T≤10), 表示数据组数.

    接下来 T 行,每行三个正整数 N、A、B。

    输出

    对每组数据:

    如果有解,输出两行,第一行一个字符串 Yes,接下来一行 N 个整数,表示排列。

    否则, 输出一行一个字符串 No。

    样例输入

    3
    4 2 2
    4 4 1
    4 3 3

    样例输出

    Yes
    3 4 1 2 
    Yes
    1 2 3 4
     No

    提示

    数据范围和子任务

    对于全部的测试数据,保证 T≤10,N≤105,∑N≤2×105T≤10,N≤105,∑N≤2×105

    子任务 1(20 分):N≤5N≤5 .

    子任务 2(30 分):每组数据均满足 N=A×BN=A×B .

    子任务 3(20 分):B≤2B≤2 .

    子任务 4(30 分):无特殊限制


    solution

    先考虑a*b=n的情况怎么做:连续构造a段下降的b

    比如 n=6 a=3 b=2

    ->      2 1 4 3 6 5

    那么如果a>n/b 呢

    就把某些段改成升序的

    由于每一段之间互不影响,所以这不会改变b的答案

    那么n!=a*b 也只是多了一段小段的而已

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define maxn 100005
    using namespace std;
    int T,n,a,b,ans[maxn],num[maxn];
    void init(){
        for(int i=1;i<=n;i++)ans[i]=num[i]=0;
    }
    int main()
    {
        freopen("seq.in","r",stdin);
        freopen("seq.out","w",stdout);
        cin>>T;
        while(T--){
            scanf("%d%d%d",&n,&a,&b);init();
            if(a+b>n+1){puts("No");continue;}
            for(int i=1;i<=n;i+=b){
                int top=i+b-1;top=min(top,n);num[i]=top-i+1;
                for(int j=top,x=0;j>=i;j--,x++)ans[j]=i+x;
            }
            int tmp=n/b;if(n%b)tmp++;
            if(tmp>a){puts("No");continue;}
            int tp=a-tmp,i=b+1;
            while(tp){
                if(tp>=num[i]-1){
                    for(int j=i;j<=i+num[i]-1;j++)ans[j]=j;
                    tp-=num[i]-1;i=i+b;
                }
                else {
                    for(int j=i;j<=i+tp-1;j++)ans[j]=j;
                    for(int j=i+num[i]-1,x=tp;j>=i+tp;j--,x++)ans[j]=i+x;
                    tp=0;
                }
            }
            puts("Yes");
            for(int i=1;i<=n;i++)cout<<ans[i]<<' ';cout<<endl;
        }
        return 0;
    }
  • 相关阅读:
    把swf反编译成fla的几种方法
    隐藏tomcat页面异常显示的版本信息
    配置Tomcat-8.5 JVM内存参数
    Nim Game
    Longest Increasing Path in a Matrix
    信息熵和信息增益
    故乡的云
    urllib编码
    odd_even_list
    Different Ways to Add Parentheses
  • 原文地址:https://www.cnblogs.com/liankewei/p/10358821.html
Copyright © 2011-2022 走看看