[洛谷P3014][USACO11FEB]牛线Cow Line (康托展开)(数论)
如果在阅读本文之前对于康托展开没有了解的同学请戳一下这里: 简陋的博客 百度百科
题目描述
N(1<=N<=20)头牛,编号为1...N,正在与FJ玩一个疯狂的游戏。奶牛会排成一行(牛线),问FJ此时的行号是多少。之后,FJ会给牛一个行号,牛必须按照新行号排列成线。
行号是通过以字典序对行的所有排列进行编号来分配的。比如说:FJ有5头牛,让他们排为行号3,排列顺序为:
1:1 2 3 4 5
2:1 2 3 5 4
3:1 2 4 3 5
因此,牛将在牛线1 2 4 3 5中。
之后,奶牛排列为“1 2 5 3 4”,并向FJ问他们的行号。继续列表:
4:1 2 4 5 3
5:1 2 5 3 4
FJ可以看到这里的答案是5。
FJ和奶牛希望你的帮助玩他们的游戏。他们需要K(1<=K<=10000)组查询,查询有两个部分:C_i将是“P”或“Q”的命令。
如果C_i是'P',则查询的第二部分将是一个整数A_i(1 <= A_i <= N!),它是行号。此时,你需要回答正确的牛线。
如果C_i是“Q”,则查询的第二部分将是N个不同的整数B_ij(1 <= B_ij <= N)。这将表示一条牛线,此时你需要输出正确的行号。
输入格式:
* 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.
下面是正文:
这是一个康托展开的(模板)题
对于n个数的全排列,这个地方我们可以运用 STL 中的next_permunation进行优化
ai代表第i个元素在未出现的元素中是第几大 即在第i~n位的元素中的rank
对与 2 1 3
对于 2 只有1比它大 所以排第1大;
对于 1 没有比它大的 所以排第0大 ;
对于 3 没有和它比较的 所以排第0大;
a3=3,a2=0,a1=0
所以ans=3;
康托展开逆运算
已知某一全排列在所有排列中排第x
可以求得 这个全排列
例如 ans=20; 求它的全排列
第一次 20/(3!) =3……2 说明在第一个元素后面有3个比现在的元素小 这个元素就是4;
第二次 2/(2!) =1……0 说明在这个元素后面有一个比它小 这只能是2;
第三次 0/(1!) =0……0 说明这个元素后面没有比它小的 只能是 1;
第四次 0/(0!) =0……0 只剩3了;
简而言之就是通过不断地向下除来实现一个降低复杂度
那么我们就可以通过这个来得到他们的序列排序了,不过这里我们要注意的一点就是这是对于整个序列所进行的一个排序,以及排序之间的空格!
下面上代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
long long n,m,fac[],vst[],a[],x;
char op;
void init() //初始化
{
for(int i=;i<=;i++) // 这里到了28就已经十分大了,所以无需再往后运算
fac[i]=;
}
ll contor(ll x[]) //Cantor的运算
{
long long ans=;
for(int i=;i<=n;i++)
{
int tag=; //标记为0
for(int j=i+;j<=n;j++)
{
if(x[i]>x[j])
tag++; //更新标记
}
ans+=tag*fac[n-i];
}
return ans+;
}
void recontor(ll x) //Cantor的逆运算
{
memset(vst,,sizeof(vst));
x--;
ll k;
for(int i=;i<=n;i++)
{
ll ans=x/fac[n-i]; //Cantor的实际操作1
for(int j=;j<=n;j++)
{
if(!vst[j])
{
if(!ans) //加入ans为0的话就赋值
{
k=j;
break; //时间上的优化
}
ans--;
}
}
printf("%d ",k);
vst[k]=; //回溯
x%=fac[n-i]; //Cantor的实际操作2
}
printf("\n");
}
int main()
{
scanf("%lld%lld",&n,&m);
init();
for(int i=;i<=n;i++)
fac[i]=i*fac[i-]; //康托展开的预处理
for(int i=;i<=m;i++)
{
cin>>op; //判断题目所给的标记
if(op=='P')
{
scanf("%lld",&x);
recontor(x); //康托展开逆运算,进行加进去
}
if(op=='Q')
{
for(int i=;i<=n;i++)
scanf("%lld",&a[i]); //康托展开运算,运算
printf("%lld\n",contor(a));
}
}
return ;
}
[洛谷P3014][USACO11FEB]牛线Cow Line (康托展开)(数论)的更多相关文章
- 洛谷 P3014 [USACO11FEB]牛线Cow Line
P3014 [USACO11FEB]牛线Cow Line 题目背景 征求翻译.如果你能提供翻译或者题意简述,请直接发讨论,感谢你的贡献. 题目描述 The N (1 <= N <= 20) ...
- P3014 [USACO11FEB]牛线Cow Line && 康托展开
康托展开 康托展开为全排列到一个自然数的映射, 空间压缩效率很高. 简单来说, 康托展开就是一个全排列在所有此序列全排列字典序中的第 \(k\) 大, 这个 \(k\) 即是次全排列的康托展开. 康托 ...
- 洛谷——P2952 [USACO09OPEN]牛线Cow Line
P2952 [USACO09OPEN]牛线Cow Line 题目描述 Farmer John's N cows (conveniently numbered 1..N) are forming a l ...
- 洛谷P3045 [USACO12FEB]牛券Cow Coupons
P3045 [USACO12FEB]牛券Cow Coupons 71通过 248提交 题目提供者洛谷OnlineJudge 标签USACO2012云端 难度提高+/省选- 时空限制1s / 128MB ...
- 洛谷 P3111 [USACO14DEC]牛慢跑Cow Jog_Sliver
P3111 [USACO14DEC]牛慢跑Cow Jog_Sliver 题目描述 The cows are out exercising their hooves again! There are N ...
- 洛谷:P2952 [USACO09OPEN]牛线Cow Line:题解
题目链接:https://www.luogu.org/problemnew/show/P2952 分析: 这道题非常适合练习deque双端队列,~~既然是是练习的板子题了,建议大家还是练练deque, ...
- 洛谷P2901 [USACO08MAR]牛慢跑Cow Jogging
题目描述 Bessie has taken heed of the evils of sloth and has decided to get fit by jogging from the barn ...
- 洛谷 P2419 [USACO08JAN]牛大赛Cow Contest
题目背景 [Usaco2008 Jan] 题目描述 N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a p ...
- 洛谷—— P2419 [USACO08JAN]牛大赛Cow Contest
https://www.luogu.org/problem/show?pid=2419 题目背景 [Usaco2008 Jan] 题目描述 N (1 ≤ N ≤ 100) cows, convenie ...
随机推荐
- Android Retrofit 2.0使用
实例带你了解Retrofit 2.0的使用,分享目前开发Retrofit遇到的坑和心得. 添加依赖 app/build.gradle 1 compile 'com.squareup.retrofit2 ...
- pycharm2018破解
1.下载 链接:https://pan.baidu.com/s/1G0C9xoUQg6JRgNQYLMIi1w 密码:2z3x 2.修改 "G:\Python\JetBrains\PyCha ...
- QT中QString 与 int float double 等类型的相互转换
Qt中 int ,float ,double转换为QString 有两种方法 1.使用 QString::number(); 如: long a = 63; QString s = QString:: ...
- Centos7.5 防火墙设置
Centos7.5默认使用firewalld作为防火墙 1.查看firewalld服务状态 systemctl status firewalld 2.查看firewalld的状态 firewall-c ...
- Bootstrap2.x与Bootstrap3.x的区别
做项目时,有时也会参考别的案例的优秀之处.在用Bootstrap的时候,发现很多项目代码都有区别,在<div>布局class上,有用.span*,有用.col-md-*,实际上是Boots ...
- 【转】Python之xml文档及配置文件处理(ElementTree模块、ConfigParser模块)
[转]Python之xml文档及配置文件处理(ElementTree模块.ConfigParser模块) 本节内容 前言 XML处理模块 ConfigParser/configparser模块 总结 ...
- Simulink--MATLAB中的一种可视化仿真工具
Simulink是MATLAB中的一种可视化仿真工具, 是一种基于MATLAB的框图设计环境,是实现动态系统建模.仿真和分析的一个软件包,被广泛应用于线性系统.非线性系统.数字控制及数字信号处理的建 ...
- 使用 Linux 系统调用的内核命令【转】
转自:http://www.ibm.com/developerworks/cn/linux/l-system-calls/ 探究 SCI 并添加自己的调用 Linux® 系统调用 —— 我们每天都在使 ...
- Oracle11g的database 和client的区别是什么?
由于工作需要,刚开始接触oracle数据库,完全小白,下载的时候看到有database和client两种类型可供下载,一时不知如何是好,于是网上询问得知其中区别,在此记录一下自己的无知. “datab ...
- 2018-2019-2-20175225 实验二《Java开发环境的熟悉》实验报告
姓名:张元瑞 学号:20175225 班级:1752 实验课程:JAVA程序设计 实验名称:Java面向对象程序设计 实验时间:2019.4.16 指导老师:娄嘉鹏 实验内容 测试点一 - " ...