HDUOJ 6852の増加と減少

HDUOJ 6852の増加と減少

トピックリンク

問題の説明

注意:1行の終わりに余分なスペースを出力しないでください。

n、x、yが与えられた場合、長さnの順列を作成して、次の条件を満たすようにしてください:

  • LIS(Longest Increeasing Subsequence)の長さはxに等しい。
  • LDS(Longest Decreasing Subsequence)の長さはyと同じです。

すべての条件を満たす複数の可能な順列がある場合は、辞書式順序で最小のものを出力します。

入力

最初の行には整数T(1≤T≤100)が含まれ、テストケースの数を示します。

各テストケースには、3つの整数n、x、y(1≤n≤1e5,1≤x、y≤n)を含む1行が含まれています。

出力

テストケースごとに、最初の行には「YES」または「NO」が含まれ、回答が存在するかどうかを示します。答えが存在する場合は、順列を示すn個の整数を含む別の行を出力します。

入力例

4
10 1 10
10 10 1
10 5 5
10 8 8

出力例

YES
10 9 8 7 6 5 4 3 2 1
YES
1 2 3 4 5 6 7 8 9 10
YES
1 2 3 5 4 10 9 8 7 6
NO

思考+構造
〜LISの長さはLDSの数であり、LDSの長さはLISの数であることが簡単にわかります〜
出力-1はn≥x ∗ y + 1 n \ geq x * y + 1ですバツそして+1n <x + y − 1 n <x + y-1<バツ+そして1
以下の構造を考えます。上記の法則に従ってnnを置くことができますnは xxに分割されますグループ xですが、質問は最小の辞書式順序を必要とします。つまり、ブロックを分割するとき、次のブロックはできるだけ大きくする必要があり、回答はスタックに格納できます。ACコードは次のとおりです。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
ll n,a,b;
int main(){
    
    
    scanf("%d",&t);
    while(t--){
    
    
        scanf("%lld%lld%lld",&n,&a,&b);
        if(n>=a*b+1||n<a+b-1) printf("NO\n");
        else{
    
    
            printf("YES\n");
            stack<int>ans;
            while(a){
    
    
                if(n-b>=a-1){
    
    
                    for(int i=n-b+1;i<=n;i++) ans.push(i);
                    n-=b;
                    a--;
                }else b=n+1-a;
            }
            while(!ans.empty()){
    
    
                printf("%d",ans.top());
                ans.pop();
                if(!ans.empty()) printf(" ");
                else printf("\n");
            }
        }
    }
    return 0;
}

おすすめ

転載: blog.csdn.net/qq_43765333/article/details/108677557