当前位置: 首页 > news >正文

Codeforces Round 1052 (Div. 2) C. Wrong Binary Searchong Binary Search

题目意思:

给一个二进制字符串,字符串下标从1开始,如果s[i]为1则i为稳定点,反正为不稳定点,需要我们依据伪代码构造一个长度为n的排序,使得排序中的每个数都满足对应s中的稳定点与不稳定点。

思路:

伪代码二分原理:
fun(x)
m为区间[l,r]上一个点
如果 p[m]==x,返回m
否则:
如果区间右端点的值大于p[m],r=m-1
否则 l=m+1

简单地说:
伪代码只会判断p[m]是否大于x!!!
伪代码只会判断p[m]是否大于x!!!
伪代码只会判断p[m]是否大于x!!!
若大于x就缩短右边界
反正缩短做左边界

而对于稳定点:
当且仅当find(x)==x时,x才为稳定点,也就是p[x]=x
若find(x)!=x,或未定义,那么x都是不稳定点,也就是p[x]!=x
要使得i点为稳定点,首先必须保证p[i]=i;

之后就要让伪代码能搜到结点i
因为伪代码任取一点m,只会判断p[m]是否大于x,如果比i大就收缩右端点
如果比i小就收缩左端点
因此只要i在区间[l,r]上就必须保证[l,i-1]上的数都小于i,[i+1,r]上的数都大于i
这样就可以使得无论在区间上取到哪个数,无论怎么收缩,i都包含在收缩后的边界内,直至搜到i
然而在所有的稳定点必然是按照从小到大排列的基础上:

1.相邻稳定点之间:如果有非稳定点,则非稳定点个数一定>=2,即2相邻稳定点之间距离=2时无效
证:
如果非稳定点个数=1,举例:s=101的情况下,1为稳定点,2为不稳定点,3为稳定点
在p[1]=1,p[3]=3的基础上,p[2]只能为2
那么p=123,结点2就成了稳定点,与s=101不符

如果非稳定点个数>=2,如非稳定点个数=2,举例:s=1001,1为稳定点,2为不稳定点,3为不稳定点 4为稳定点
下标区间[2,3]只要做到比1大,比4小即可,那么 p=1324 同样可以保证 1,4稳定,2,3不稳定
因为伪代码任取一点m,只会判断p[m]是否大于x,
区间上除1之外的所有点都是比1大的,所以在搜索1时只会不断收缩右边界,直至搜到1
区间上除4之外的所有点都是比4大的,所以在搜索4时只会不断收缩左边界,直至搜到4
非稳定点个数>2时同理

2.最小稳定点之前:如果有非稳定点,则非稳定点个数一定>=2,即第一个稳定点为2时无效
如果非稳定点个数=1,举例:s=011的情况下,1为不稳定点,2为稳定点,3为稳定点
p[1]的位置只能是1,此时i就成了稳定点,与s不符

如果非稳定点个数>=2,如非稳定点个数=2,举例:s=0011,1为不稳定点,2为不稳定点,3为稳定点 4为稳定点
p可以为1234,也可以为2134;当p=2134时,因为所有数都比3,4小所以会不断收缩左边界
非稳定点个数>2时同理

3.最大稳定点之后:如果有非稳定点,则非稳定点个数一定>=2,即最后一个稳定点为n-1时无效
证明过程同2.

在上述推导过程中不难看出,在构造排序时,可以利用稳定点将整个排序拆分成若干子区间
在子区间上逆序构造排序即可

AC代码:

#include<iostream>
#include<vector>
using namespace std;
vector<int> a;//存储所有稳定点
vector<int> p;
void build(int l, int r) {//构造函数int len = r - l + 1;if (len % 2 == 0) {for (int i = r;i >= l;i--) {p.push_back(i);}}else {int k = (r + l) / 2;for (int i = r;i >= l;i--) {if (i != k) {p.push_back(i);}}p.push_back(k);}
}
int main() {int t;cin >> t;getchar();while (t--) {a.clear();p.clear();int n;cin >> n;getchar();string s;cin >> s;a.push_back(0);for (int i = 0;i < n;i++) {if (s[i] == '1') {a.push_back(i + 1);}}if (a.size() == 1) {//没有稳定点cout << "YES" << endl;for (int i = n;i >= 1;i--) {cout << i << " ";}cout << endl;}else if (a.size() == n + 1) {//所有点都是稳定点cout << "YES" << endl;for (int i = 1;i <= n;i++) {cout << i << " ";}cout << endl;}else {bool flag = 1;int ll = a[1];//第一个稳定点int rr = a.back();//最后一个稳定点if (ll == 2 || rr == n - 1) {cout << "NO" << endl;continue;}for (int i = 1;i < a.size();i++) {if (a[i] - a[i - 1] == 2) {//稳定点之间距离=2且不为0flag = 0;break;}}if (!flag) {cout << "NO" << endl;}else {	cout << "YES" << endl;//  构造排序for (int i = 1;i < a.size();i++) {int l = a[i - 1] + 1;int r = a[i] - 1;if (l < r) {build(l, r);}p.push_back(a[i]);}if (a.back() < n) {//处理末尾int l = a.back() + 1;int r = n;build(l, r);}for (int i : p) {cout << i << " ";}cout << endl;}}}return 0;
}

http://www.dtcms.com/a/418384.html

相关文章:

  • 网站开始怎么做的做网站用php还是html
  • 算法基础篇(7)双指针
  • 从零开始学华为:Console口连接设备
  • 华为bgp路由的各种控制和团体属性及orf使用案例
  • 网站中的表单怎么做吉林网页制作公司
  • 【开题答辩全过程】以 Python基于大数据的四川旅游景点数据分析与可视化为例,包含答辩的问题和答案
  • MySQL复合查询(重点)
  • Java面试揭秘:从Spring Boot到微服务的技术问答
  • 【项目】自然语言处理——情感分析 <上>
  • 生态碳汇涡度相关监测与通量数据分析实践技术应用
  • 【linux内核驱动day04】
  • 安全笔记(一)
  • 17-Language Modeling with Gated Convolutional Networks
  • ES启用Xpack,配置ssl证书
  • 网站无收录的原因湖南长沙微信平台号
  • k8s-pod的启动
  • RHCA - CL260 | Day11:管理存储集群
  • 多线程环境下处理Flask上下文问题的文档
  • 第四部分:VTK常用类详解(第95章 vtkLegendBoxActor图例框演员类)
  • 网站模板_网站模板源码_免费企业模板源码—免费网站模板源码下载
  • 伽利略 | 近代科学的奠定 / 函数观念的演变
  • 四川网站建设益友微信公众号运营规则
  • 专业的短视频发布矩阵哪家靠谱
  • 线性代数(标量与向量+矩阵与张量+矩阵求导)
  • 济南免费网站建站模板免费网站建设软件大全
  • 【OpenHarmony】用户文件服务模块架构
  • 网站建设早会说什么建设一个网站的需求分析
  • [C++项目组件]cpp-httplib与 websocketpp的简单介绍和使用
  • 奈奎斯特采样定理
  • 做购物网站需要什么服务器网站设计 手写