[CC-SEAPERM2]Sereja and Permutations

题目大意:

有一个\(n(n\le300)\)排列\(p\),将其中一个元素\(p_i\)拿掉,然后将原来大于\(p_i\)的元素减一,这样就得到一个新的排列。

将\(p\)中每一个数拿掉之后都会得到一个新的排列,这样就得到了\(n\)个新的排列。

现在给出最后得到的\(n\)个新的排列(顺序随机),请求出原来的排列。如果有多个解,输出字典序最小的解。保证至少有一个解。

思路:

枚举哪一个排列被删掉了\(p_1\),那么剩下排列的第一个数,要么是\(p_1\),要么是\(p_1-1\)。(如果剩下不止两种数,或者相差超过\(1\),说明被删去\(p_1\)的不可能是这个排列。)

这样,我们就可以得到\(p_1\),从而得到初始的排列,但是我们还要删去每一个数看看是否和给你的排列一样来验证。做法是hash+map。

时间复杂度\(\mathcal O(n^3)\)。

源代码:

#include<map>
#include<cstdio>
#include<cctype>
#include<climits>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
typedef unsigned long long uint64;
const int N=301;
const uint64 base=31;
bool have_ans;
int n,a[N][N],b[N],ans[N];
std::map<uint64,int> map;
inline uint64 hash(int a[]) {
uint64 ret=0;
for(register int i=1;i<n;i++) {
ret=ret*base+a[i];
}
return ret;
}
inline bool check() {
for(register int i=1;i<=n;i++) {
if(b[i]<ans[i]) return true;
if(b[i]>ans[i]) return false;
}
return false;
}
inline void upd() {
if(!have_ans||check()) {
have_ans=true;
for(register int i=1;i<=n;i++) ans[i]=b[i];
}
}
int main() {
for(register int T=getint();T;T--) {
n=getint();
if(n==1) {
puts("1");
return 0;
}
for(register int i=1;i<=n;i++) {
for(register int j=1;j<n;j++) {
a[i][j]=getint();
}
}
have_ans=false;
for(register int i=1;i<=n;i++) {
int max[2]={0,0};
bool three=false;
for(register int j=1;j<=n;j++) {
if(i!=j) {
int tmp=a[j][1];
if(tmp==max[0]||tmp==max[1]) continue;
for(register int k=0;k<2;k++) {
if(tmp>max[k]) std::swap(max[k],tmp);
}
three|=tmp;
}
}
if(three||(max[1]&&max[0]-max[1]!=1)) continue;
for(register int val=max[0];val<=max[0]+1;val++) {
for(register int i=1;i<=n;i++) map[hash(a[i])]++;
b[1]=val;
for(register int j=2;j<=n;j++) b[j]=a[i][j-1]+(a[i][j-1]>=b[1]);
for(register int i=1;i<=n;i++) {
uint64 ret=0;
for(register int j=1;j<=n;j++) {
if(i!=b[j]) ret=(uint64)ret*base+b[j]-(b[j]>i);
}
map[ret]--;
}
bool flag=true;
for(auto &i:map) {
if(i.second!=0) flag=false;
}
map.clear();
if(flag) upd();
}
}
for(register int i=1;i<=n;i++) {
printf("%d%c",ans[i]," \n"[i==n]);
}
}
return 0;
}

[CC-SEAPERM2]Sereja and Permutations的更多相关文章

  1. CodeChef November Challenge 2014

    重点回忆下我觉得比较有意义的题目吧.水题就只贴代码了. Distinct Characters Subsequence 水. 代码: #include <cstdio> #include ...

  2. CF380C. Sereja and Brackets[线段树 区间合并]

    C. Sereja and Brackets time limit per test 1 second memory limit per test 256 megabytes input standa ...

  3. Atitti.dw cc 2015 绿色版本安装总结

    Atitti.dw cc 2015 绿色版本安装总结 1.1. 安装程序无法初始化.请下载adobe Support Advisor检测该问题.1 1.1.1. Adobe Application M ...

  4. Permutations II

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  5. [LeetCode] Permutations II 全排列之二

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  6. [LeetCode] Permutations 全排列

    Given a collection of numbers, return all possible permutations. For example,[1,2,3] have the follow ...

  7. POJ2369 Permutations(置换的周期)

    链接:http://poj.org/problem?id=2369 Permutations Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  8. 【Hello CC.NET】CC.NET 实现自动化集成

    一.背景 公司的某一金融项目包含 12 个子系统,新需求一般按分支来开发,测完后合并到主干发布.开发团队需要同时维护开发环境.测试环境.模拟环境(主干).目前面临最大的两个问题: 1.子系统太多,每次 ...

  9. 浅谈iptables防SYN Flood攻击和CC攻击

    ------------------------本文为自己实践所总结,概念性的东西不全,这里粗劣提下而已,网上很多,本文主要说下目前较流行的syn洪水攻击和cc攻击------------------ ...

随机推荐

  1. matlab转c++代码实现(主要包含C++ std::vector,std::pair学习,包含数组与常数相乘,数组相加减,将数组拉成一维向量,图片的读入等内容)

    MATLAB部分: xmap = repmat( linspace( -regionW/2, regionW/2, regionW), regionH, 1 );%linspace [x1,x2,N] ...

  2. Just Oj 2017C语言程序设计竞赛高级组E: DATE ALIVE(二分匹配)

    E: DATE ALIVE 时间限制: 1 s      内存限制: 128 MB 提交 我的状态 题目描述 五河士道家里的精灵越来越多了,而每一个精灵都想和他有一个约会.然而五河士道却只有一个,无奈 ...

  3. #20165323 Java实验四 Android程序设计

    一.实验报告封面 课程:Java程序设计 班级:1653班 姓名:杨金川 学号:20165323 指导教师:娄嘉鹏 实验日期:2018年5月14日 实验时间:13:45 - 15:25 实验序号:实验 ...

  4. 小程序wx.getUserInfo获取用户信息方案介绍

    问题模块 框架类型 问题类型 API/组件名称 终端类型 操作系统 微信版本 基础库版本 API和组件 - -   - -     背景 小程序一个比较重要的能力就是获取用户信息,也就是使用 wx.g ...

  5. alpha冲刺5/10

    目录 摘要 团队部分 个人部分 摘要 队名:小白吃 组长博客:hjj 作业博客:冲刺5 团队部分 后敬甲(组长) 过去两天完成了哪些任务 文字描述 最近事情有点多,只是跟进了下进度,写了写博客 接下来 ...

  6. 第二种掌握的排序Q-Q

    #include<stdio.h> int main() {     int s[10000]={0};     int i=0,j=0,n=0,x=0;     scanf(" ...

  7. day5.python列表练习题

    写代码,有如下列表,按照要求实现每一个功能 li = [“alex”, “WuSir”, “ritian”, “barry”, “wenzhou”] 1.计算列表的长度并输出 print(len(li ...

  8. 桐桐的数学游戏(N皇后)

    题目描述 相信大家都听过经典的“八皇后”问题吧?这个游戏要求在一个8×8的棋盘上放置8个皇后,使8个皇后互相不攻击(攻击的含义是有两个皇后在同一行或同一列或同一对角线上). 桐桐对这个游戏很感兴趣,也 ...

  9. 同构体字符串(如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。 所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。)

    示例 1: 输入: s = "egg", t = "add" 输出: true 示例 2: 输入: s = "foo", t = " ...

  10. 035 控制并发 select * from test1 where id =1 for update 就会对这行加锁了?

    今天在看同事程序的时候,看到这种用法,顺便学习下. 一:理论 1.功能 这个功能是上锁. 上的是一个排它锁,也就是说,其他的事务是可以读取的.但是不能写入或者更新. 二:实践 1.创建表 2.提交一条 ...