牛客 - 字典序(思维)
题目链接:点击查看
题目大意:给出一个长度为 n 的数列 a ,构造 s[ i ] 是数列 a 去掉 a[ i ] 后的数列,现在需要对 s 排序,输出排序后的结果
题目分析:一提到排序,可以试着写一下 sort 的 cmp ,然后剩下的就不用我们操心了
对于 cmp 函数,我们的目标是给出两个位置 x 和 y ,从而确定其相应的大小
首先假设 x < y ,这个时候,数列 s[ x ] 和 数列 s[ y ] 的长度肯定是相等的
如上图所示,我们可以将整个数列分为三段,其中对于第一段和第三段而言,s[ x ] 和 s[ y ] 是完全相同的,只有在第二段中,这 y - x 个数是交叉对应的,我们为了比较两个数列的大小,只需要找到位置 x 后的首个位置 pos ,满足 a[ pos ] != a[ pos + 1 ] ,这个时候判断一下这两个数的大小就能比较出两个数列的大小了,这里需要注意的点是,pos 需要满足在区间 [ x , y ) 才行,如果 pos 不在这个区间内的话,就说明 s[ x ] 和 s[ y ] 的第二段是相等的,综上得出 s[ x ] 和 s[ y ] 是相等的
接下来考虑 x > y 的情况,其实就是上面把 x 和 y 的位置换一下,思路完全一样
最后的问题就是,如何快速找到这个位置 pos 呢,我采取的一个方法就是,预处理把 a[ i ] != a[ i + 1 ] 的所有 i 都放到一个 vector 里,然后就可以二分查找了,这样总的时间复杂度是 nlognlogn,对于 n = 1e5 的数据还是绰绰有余的
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<unordered_map>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e6+100;int a[N],ans[N];vector<int>pos;int main()
{
#ifndef ONLINE_JUDGE
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);int w;cin>>w;while(w--){pos.clear();int n;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",a+i);ans[i]=i;}for(int i=1;i<n;i++)if(a[i]!=a[i+1])pos.push_back(i);//a[i]和a[i+1]不同pos.push_back(inf);sort(ans+1,ans+1+n,[&](int x,int y){if(x<y){int j=lower_bound(pos.begin(),pos.end(),x)-pos.begin();if(pos[j]<y)return a[pos[j]+1]<a[pos[j]]; }else{int j=lower_bound(pos.begin(),pos.end(),y)-pos.begin();if(pos[j]<x)return a[pos[j]+1]>a[pos[j]];}return x<y;});printf("%d",ans[1]);for(int i=2;i<=n;i++)printf(" %d",ans[i]);puts("");}return 0;
}
牛客 - 字典序(思维)相关推荐
- 生成树(光棍 牛客, 思维)
链接:https://ac.nowcoder.com/acm/contest/223/A 来源:牛客网 题目描述 你有一张n个点的完全图(即任意两点之间都有无向边) 现在给出这张图的两棵生成树 定义一 ...
- 牛客 - Hash(思维+进制转换)
题目链接:点击查看 题目大意:给出一个长度为 6 的字符串 s ,再给出模数 mod,现在规定哈希值为如下运算: const int LEN = 6; int mod; int Hash(char s ...
- 牛客 - 交换(思维+找循环节)
题目链接:点击查看 题目大意:给出一个数列 n ,要求通过交换使其从小到大排序的最小次数 题目分析:第一反应是求逆序对,把之前做过的题目贴过来结果只过了 10% ,静下心来又读了一下题,发现这个题目要 ...
- 牛客月赛思维题使徒袭来
使徒袭来 参考均值不等式 得到: 3×x1x2x33≤x1+x2+x33\times\sqrt[3]{x_1x_2x_3}\leq x_1+x_2+x_3 3×3x1x2x3≤x1+x2+ ...
- 牛客竞赛36签到题A(思维)
//第一题签到(第一次做牛客的诶) 链接:https://ac.nowcoder.com/acm/contest/328/A 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C+ ...
- 牛客练习赛34 - C little w and Segment Coverage(思维、树状数组)
title: 牛客练习赛34 - C little w and Segment Coverage(思维.树状数组) date: 2018-12-15 16:36:55 tags: [树状数组,思维] ...
- 牛客题霸 [拼接所有的字符串产生字典序最小的字符串] C++题解/答案
牛客题霸 [拼接所有的字符串产生字典序最小的字符串] C++题解/答案 题目描述 给定一个字符串的数组strs,请找到一种拼接顺序,使得所有的字符串拼接起来组成的字符串是所有可能性中字典序最小的,并返 ...
- 【牛客 - 188C】水图(bfs树的直径,思维)
题干: 链接:https://ac.nowcoder.com/acm/contest/188/C 来源:牛客网 小w不会离散数学,所以她van的图论游戏是送分的 小w有一张n个点n-1条边的无向联通图 ...
- 【牛客练习赛13】 A B C D【康拓展开】 E【DP or 记忆化搜索】 F 【思维】
A 幸运数字Ⅰ 链接:https://www.nowcoder.com/acm/contest/70/A 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K, ...
最新文章
- python读取浮点数与源文件不同
- python显示语言错误_Python错误和异常
- wxWidgets:引用计数
- 设计模式是什么鬼(备忘录)
- asp mysql添加数据_ASP:ado.net 实例向数据库添加数据。
- 区块链学习笔记:DAY05 如何使用公有云区块链服务
- 2016年度十大新兴技术出炉,你最看好哪个?
- struts2中action的class属性值意义
- apache指定的网络名不再可用错误解决方法
- 2019第十届蓝桥杯B组C++省赛E题迷宫--BFS(倒搜)
- Navicat 安装过程问题总结
- python实现QQ自动发送信息
- wps居中对齐不在中间_wps有时候居中对齐不是在中间
- 逍遥模拟器获取服务器信息出错,前沿科技资讯:逍遥安卓模拟器网络不稳定如何办(显示网络异常解决方法)...
- 2017美团网易360部分笔试题
- 快手涨收近95港币,年初至今已涨超30%
- java后台框架 springmvc mybaits 集代码生成器 SSM SSH
- 《Spring响应式微服务》读书笔记
- 挑战程序设计竞赛 3.6 与平面和空间打交道的计算几何
- 残忍的沟里学姐 (数据结构作业)