zoukankan      html  css  js  c++  java
  • bzoj 3301 Cow Line

    题目大意:

    n的排列,K个询问

    为P时,读入一个数x,输出第x个全排列

    为Q时,读入N个数,求这是第几个全排列

    思路:

    不知道康拓展开是什么,手推了一个乱七八糟的东西

    首先可以知道

    把排列看成是一个每一位进制不同的数

    每一位进制可以看做是:

    (n-1)!   (n-2)!  ...... 2 1 1 

    然后对于第一种询问

    像正常进制转换一样,处理出每一位应该填第几个数

    这时需要处理一下哪些数可以被取到

    然后取可以取到的数里的第“几”个 每一位输出就可以了

    对于第二种询问

    直接一位一位减,同样在处理的时候记录哪些数可以被取到

    答案+=每一位进制*该位置权值

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<queue>
     9 #define inf 2139062143
    10 #define ll long long
    11 #define MAXN 100100
    12 using namespace std;
    13 inline ll read()
    14 {
    15     ll x=0,f=1;char ch=getchar();
    16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    18     return x*f;
    19 }
    20 ll n,T,t[22],x,pos,vis[22],i,cnt,tot,res,f;
    21 char ch[2];
    22 int main()
    23 {
    24     n=read();
    25     t[n]=t[n-1]=1;
    26     for(i=n-2;i;i--) t[i]=t[i+1]*(n-i);
    27     //cout<<t[1]<<endl;
    28     for(T=read();T;T--)
    29     {
    30         scanf("%s",ch);
    31         pos=1,tot=f=0;
    32         memset(vis,0,sizeof(vis));
    33         if(ch[0]=='P')
    34         {
    35             x=read()-1;
    36             while(x)
    37             {
    38                 while(x<t[pos]) 
    39                 {
    40                     for(i=1;i<=n;i++) if(!vis[i])
    41                     {
    42                         if(f) printf(" %lld",i);else {printf("%lld",i);f=1;}
    43                         break;
    44                     }
    45                     vis[i]=1;
    46                     pos++;
    47                 }
    48                 while(x>=t[pos]) x-=t[pos],cnt++;
    49                 for(i=1;i<=n&&cnt!=-1;i++) if(!vis[i]) cnt--;
    50                 vis[i-1]=1,tot++,cnt=0,pos++;
    51                 if(f) printf(" %lld",i-1);else {printf("%lld",i-1);f=1;}
    52             }
    53             if(tot!=n)
    54                 for(i=1;i<=n;i++)
    55                     if(!vis[i])
    56                         if(f) printf(" %lld",i);else {printf("%lld",i);f=1;}
    57             puts("");
    58         }
    59         else
    60         {
    61             res=0;
    62             for(i=1;i<=n;i++) 
    63             {
    64                 x=read();
    65                 for(ll j=1;j<x;j++) if(!vis[j]) cnt++;
    66                 res+=t[i]*cnt;
    67                 vis[x]=1,cnt=0;
    68             }
    69             printf("%lld
    ",res+1);
    70         }
    71     }
    72 }
    View Code
  • 相关阅读:
    如何解决Ubuntu下的的“system program problem detected”
    GDM, KDM, LightDM, SDDM显示管理器的区别和安装配置
    在Linux下安装使用vokoscreen录制网站上的视频与声音-Ubuntu-mate-20.04桌面环境测试录屏推荐
    Ubuntu-mate-20.04-desktop安装总结
    云上渗透-基于阿里云环境渗透
    fastadmin前台getshell漏洞
    gitlab CI/CD Custom SAST
    前端神器RRWEB
    【转】六种减小Docker镜像大小的方法
    splunk 多个数据关联查询
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/8535625.html
Copyright © 2011-2022 走看看