zoukankan      html  css  js  c++  java
  • 构造——cf1311E好题

    /*
    对于每个n,满足条件的d总是在一段区间内
    d的最小值就是完全二叉树的dmin,最大值是链的dmax 
    [dmin,dmax]这段区间内的所有值都可以取到    
        策略:先构造一棵n个点的完全二叉树,自底层向上判断,每次只把一个可以往下挪的点往下挪
        这样每次d只会+1
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define N 5005
    int num[N],h;
    int main(){
        int t;cin>>t;
        while(t--){
            h=0;
            memset(num,0,sizeof num);
            int n,d;
            cin>>n>>d;
            
            int dmin=0,dmax=0;
            int tmp=n;
            while(tmp){
                h++;
                if(tmp>=(1<<(h-1))){
                    tmp-=(1<<(h-1));
                    dmin+=(1<<(h-1))*(h-1);
                    num[h]=(1<<(h-1));
                }else {
                    dmin+=tmp*(h-1);
                    num[h]=tmp;
                    tmp=0;
                }
            }
            for(int i=1;i<=n;i++)dmax+=i-1;
            if(d<dmin || d>dmax){puts("NO");continue;}
            
            d-=dmin;
            while(d){
                d--;
                for(int i=h+1;i>=2;i--){
                    if(num[i]+1<=2*(num[i-1]-1)){
                        num[i]++;
                        num[i-1]--;
                        if(i==h+1)h=i;
                        break;
                    }
                }
            }
            puts("YES");
            int now=1;
            for(int i=2;i<=h;i++){
                for(int j=1;j<=num[i];j++)
                    cout<<now+(j+1)/2-1<<" ";
                now+=num[i-1];
            }
            puts("");
        }
    } 
    /*
    对于每个n,满足条件的d总是在一段区间内
    d的最小值就是完全二叉树的dmin,最大值是链的dmax 
    [dmin,dmax]这段区间内的所有值都可以取到    
        策略:先构造一棵n个点的完全二叉树,自底层向上判断,每次只把一个可以往下挪的点往下挪
        这样每次d只会+1
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define N 5005
    int num[N],h;
    int main(){
        int t;cin>>t;
        while(t--){
            h=0;
            memset(num,0,sizeof num);
            int n,d;
            cin>>n>>d;
            
            int dmin=0,dmax=0;
            int tmp=n;
            while(tmp){
                h++;
                if(tmp>=(1<<(h-1))){
                    tmp-=(1<<(h-1));
                    dmin+=(1<<(h-1))*(h-1);
                    num[h]=(1<<(h-1));
                }else {
                    dmin+=tmp*(h-1);
                    num[h]=tmp;
                    tmp=0;
                }
            }
            for(int i=1;i<=n;i++)dmax+=i-1;
            if(d<dmin || d>dmax){puts("NO");continue;}
            
            d-=dmin;
            while(d){
                d--;
                for(int i=h+1;i>=2;i--){
                    if(num[i]+1<=2*(num[i-1]-1)){
                        num[i]++;
                        num[i-1]--;
                        if(i==h+1)h=i;
                        break;
                    }
                }
            }
            puts("YES");
            int now=1;
            for(int i=2;i<=h;i++){
                for(int j=1;j<=num[i];j++)
                    cout<<now+(j+1)/2-1<<" ";
                now+=num[i-1];
            }
            puts("");
        }
    } 
  • 相关阅读:
    Entity Framework6 with Oracle(可实现code first)
    ORACLE官方全托管驱动 Oracle.ManagedDataAccess 12.1.0.1.0
    C#连接Oracle数据库的四种方法
    WPF的TextBox产生内存泄露的情况
    ArcGIS客户端API中加载大量数据的几种解决办法(以Silverlight API为例)
    ArcGISDynamicMapServiceLayer 和 ArcGISTiledMapServiceLayer 区别
    ArcGIS客户端API中加载大量数据的几种解决办法
    MVVM中间接使用事件(命令)
    Tornaod框架
    跨站请求伪造CSRF
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12487634.html
Copyright © 2011-2022 走看看