zoukankan      html  css  js  c++  java
  • P3014 [USACO11FEB]牛线Cow Line

    题目描述

    The N (1 <= N <= 20) cows conveniently numbered 1...N are playing yet another one of their crazy games with Farmer John. The cows will arrange themselves in a line and ask Farmer John what their line number is. In return, Farmer John can give them a line number and the cows must rearrange themselves into that line.

    A line number is assigned by numbering all the permutations of the line in lexicographic order.

    Consider this example:

    Farmer John has 5 cows and gives them the line number of 3.

    The permutations of the line in ascending lexicographic order: 1st: 1 2 3 4 5

    2nd: 1 2 3 5 4

    3rd: 1 2 4 3 5

    Therefore, the cows will line themselves in the cow line 1 2 4 3 5.

    The cows, in return, line themselves in the configuration '1 2 5 3 4' and ask Farmer John what their line number is.

    Continuing with the list:

    4th : 1 2 4 5 3

    5th : 1 2 5 3 4

    Farmer John can see the answer here is 5

    Farmer John and the cows would like your help to play their game. They have K (1 <= K <= 10,000) queries that they need help with. Query i has two parts: C_i will be the command, which is either 'P' or 'Q'.

    If C_i is 'P', then the second part of the query will be one integer A_i (1 <= A_i <= N!), which is a line number. This is Farmer John challenging the cows to line up in the correct cow line.

    If C_i is 'Q', then the second part of the query will be N distinct integers B_ij (1 <= B_ij <= N). This will denote a cow line. These are the cows challenging Farmer John to find their line number.

    输入输出格式

    输入格式:

    • Line 1: Two space-separated integers: N and K

    • Lines 2..2*K+1: Line 2*i and 2*i+1 will contain a single query.

    Line 2*i will contain just one character: 'Q' if the cows are lining up and asking Farmer John for their line number or 'P' if Farmer John gives the cows a line number.

    If the line 2*i is 'Q', then line 2*i+1 will contain N space-separated integers B_ij which represent the cow line. If the line 2*i is 'P', then line 2*i+1 will contain a single integer A_i which is the line number to solve for.

    输出格式:

    • Lines 1..K: Line i will contain the answer to query i.

    If line 2*i of the input was 'Q', then this line will contain a single integer, which is the line number of the cow line in line 2*i+1.

    If line 2*i of the input was 'P', then this line will contain N space separated integers giving the cow line of the number in line 2*i+1.

    输入输出样例

    输入样例#1:
    5 2 
    P 
    3 
    Q 
    1 2 5 3 4 
    
    输出样例#1:
    1 2 4 3 5 
    5 

    题意:

    有N头牛,和K个询问

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

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

    通过康托展开 求第x个全排列 求某个全排列是第几个

    对于n个数的全排列
    康托展开

    ai代表第i个元素在未出现的元素中是第几大 即在第i~n位的元素中排第几

    对与 2 1 3
    对于 2 只有1比它大 所以排第1大
    对于 1 没有比它大的 所以排第0大
    对于 3 没有和它比较的 所以排第0大
    a3=3 a2=0a1=0

    ans=3;

    康托展开逆运算
    已知某一全排列在所有排列中排第x
    可以求得 这个全排列

    例如 ans=20; 求它的全排列
    核心是这样的一张图
    Cantor

    第一次 20/(3!) =3……2 说明在第一个元素后面有3个比现在的元素小 这个元素就是4
    第二次 2/(2!) =1……0 说明在这个元素后面有一个比它小 这只能是2
    第三次 0/(1!) =0……0 说明这个元素后面没有比它小的 只能是 1
    第四次 0/(0!) =0……0 只剩3了


     1 /*
     2     把1 2 3 4 5 视为第0种排列
     3       1 2 3 5 4 视为第1种排列 
     4     所以寻找第x种排列时 x 要减1
     5     
     6     同理 ans要加1 
     7 */
     8 #include <vector>
     9 #include <cctype>
    10 #include <cstdio>
    11 #include <iostream>
    12 #include <algorithm>
    13 
    14 using namespace std;
    15 
    16 typedef long long LL;
    17 
    18 const int MAXN=30;
    19 
    20 int n,m;
    21 
    22 int s[MAXN];
    23 
    24 LL a[MAXN];
    25 
    26 char c[5];
    27 
    28 inline void read(int&x) {
    29     int f=1;register char c=getchar();
    30     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());
    31     for(;isdigit(c);x=x*10+c-48,c=getchar());
    32     x=x*f;
    33 }
    34 
    35 inline LL The_num() {
    36     LL ans=0;
    37     for(int i=1;i<=n;++i) {
    38         int t=0;
    39         for(int j=i+1;j<=n;++j) 
    40           if(s[i]>s[j]) ++t;
    41         ans+=t*a[n-i];
    42     }
    43     return ans;
    44 }
    45 
    46 inline void The_permutation(LL k) {
    47     --k;
    48     vector<int> v,ans;
    49     for(int i=1;i<=n;++i) 
    50       v.push_back(i);
    51     for(int i=n;i>=1;--i) {
    52         LL r=k%a[i-1];
    53         LL b=k/a[i-1];
    54         k=r;
    55         sort(v.begin(),v.end());
    56         ans.push_back(v[b]);
    57         v.erase(v.begin()+b);
    58     }
    59     vector<int>::iterator it;
    60     for(it=ans.begin();it!=ans.end();++it) 
    61       printf("%d ",*it);
    62     printf("
    ");
    63     return;
    64 }
    65 
    66 int hh() {
    67 //    freopen("permutation.in","r",stdin);
    68 //    freopen("permutation.out","w",stdout);
    69     LL x;
    70     read(n);read(m);
    71     a[0]=1;
    72     for(int i=1;i<=n;++i) a[i]=a[i-1]*i;
    73     for(int i=1;i<=m;++i) {
    74         scanf("%s",c);
    75         if(c[0]=='P')  {
    76             cin>>x;
    77             The_permutation(x);
    78         }
    79         else if(c[0]=='Q') {
    80             for(int j=1;j<=n;++j) read(s[j]);
    81             LL ans=The_num();
    82             printf("%lld
    ",ans+1);
    83         }
    84     }
    85     return 0;
    86 }
    87 
    88 int sb=hh();
    89 int main(int argc,char**argv) {;}
    代码







    作者:乌鸦坐飞机
    出处:http://www.cnblogs.com/whistle13326/
    新的风暴已经出现 怎么能够停止不前 穿越时空 竭尽全力 我会来到你身边 微笑面对危险 梦想成真不会遥远 鼓起勇气 坚定向前 奇迹一定会出现

     
  • 相关阅读:
    【20171227】json
    【20171224】文件操作
    【20171225】编解码
    【20171226】urllib
    【20171226】requests
    【错误集】编解码
    Python 基础概念——单例设计模式
    Python 继承
    python面向对象概述
    Python基础_函数的递归
  • 原文地址:https://www.cnblogs.com/whistle13326/p/7485184.html
Copyright © 2011-2022 走看看