点此看题面

大致题意: 给你一个长度为\(n\)的排列\(p\),要求构造一个合法的括号序列,使得如果第\(i\)个位置是左括号,则第\(p_i\)个位置一定是右括号。

暴搜

很容易想出一个暴搜。

即对于每一个没有确定的位置\(x\),无非有两种情况:

  • 选左括号。前提是\(p_x\)没被选过或者\(p_x\)为右括号,然后标记第\(p_x\)位为右括号。
  • 选右括号。我们可以开一个变量\(v\)来记录左括号个数\(-\)有括号个数,则选右括号的前提是\(v>0\)。(因为要是一个合法的括号序列)

最后判断\(v\)是否恰好等于\(0\)即可。

代码如下:

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100
using namespace std;
int n,a[N+5];char s[N+5];
I void dfs(CI x,CI v)//x记录当前位置,v记录左括号个数减右括号个数
{
if(x>n) return (void)(!v&&(puts(s+1),exit(0),0));//如果x大于n且v恰好为0,则输出答案,退出程序
if(s[x])//如果已经确定
{
if(s[x]^')') return dfs(x+1,v+1);//如果是左括号,搜索下一位
if(v) return dfs(x+1,v-1);return;//如果是右括号且v大于0,搜索下一位
}
if(a[x]>x||s[a[x]]^'(') s[x]='(',s[a[x]]=')',dfs(x+1,v+1),s[x]=s[a[x]]='\0';//选左括号
if(v) s[x]=')',dfs(x+1,v-1),s[x]='\0';//选右括号
}
int main()
{
RI i;for(scanf("%d",&n),i=1;i<=n;++i) scanf("%d",a+i);//读入
return dfs(1,0),0;
}

所以这样就有\(81\)分了。

如果你是常数之神,说不定能直接过。

观察性质

接下来,我们要观察一下这个题目中的一个性质。

注意到它保证有解,再结合题意,如果我们把\(i->p_i\)看成一条边,则原序列可以看成若干个环,而这些环一定都是偶环(不然就无解了)。

而对于一个偶环,我们对它的选择必然是左括号与右括号相交替的。

也就是说,对于一个偶环,只有两种选择方法,似乎暴枚即可。

然而,要特判环长为\(2\)的情况(不然会像我第一次那样只有\(86\)分——也就比暴搜多\(5\)分),贪心一下即可发现肯定是左边那位选左括号,右边那位选右括号。

这样就能过了。

关于时间复杂度有严谨的证明:

考虑我们特判了环长为\(2\)的情况,也就是说环长至少为\(4\)。

则最多\(100÷4=25\)个环,而\(2^{25}\)稳过。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100
using namespace std;
int n,tot,a[N+5],v[N+5];char s[N+5];vector<int> f[N+5];
I void Check()//验证是否为合法括号序列
{
for(RI i=1,t=0;i<=n;++i) if((t+=(s[i]^')'?1:-1))<0) return;//若出现不合法,直接退出函数
puts(s+1),exit(0);//合法则输出答案,退出程序
}
I void dfs(CI x)//搜索,判断第i个环的填法
{
if(x>tot) return Check();RI i,sz=f[x].size();
if(!(sz^2)) return s[f[x][0]]='(',s[f[x][1]]=')',dfs(x+1);//特判环长为2的情况
for(i=0;i^sz;++i) s[f[x][i]]=(i&1?'(':')');dfs(x+1);//环中必然是左右括号交替
for(i=0;i^sz;++i) s[f[x][i]]=(i&1?')':'(');dfs(x+1);//枚举另一种情况
}
int main()
{
RI i,x;for(scanf("%d",&n),i=1;i<=n;++i) scanf("%d",a+i);//读入
for(i=1;i<=n;++i) if(!v[x=i])//如果没访问过
{++tot;W(!v[x]) v[x]=1,f[tot].push_back(x),x=a[x];}//找环
return dfs(1),0;//搜索
}

【LOJ6043】「雅礼集训 2017 Day7」蛐蛐国的修墙方案(搜索技巧题)的更多相关文章

  1. loj6043 「雅礼集训 2017 Day7」蛐蛐国的修墙方案

    传送门:https://loj.ac/problem/6043 [题解] 我们考虑这是个置换,所以一定形成了很多不相交的环. 对于每个环,我们只能选一段.不选.选一段.不选这样交替下去. 显然只有偶环 ...

  2. LOJ #6043. 「雅礼集训 2017 Day7」蛐蛐国的修墙方案

    我可以大喊一声这就是个SB题吗? 首先讲一句如果你像神仙CXR一样精通搜索你就可以得到\(80pts\)(无Subtask)的好成绩 我们考虑挖掘一下题目的性质,首先发现这是一个置换,那么我们发现这的 ...

  3. 【复杂度分析】loj#6043. 「雅礼集训 2017 Day7」蛐蛐国的修墙方案

    感觉有点假 题目大意 数据范围:$n<=100$ 题目分析 由于题目给出的是 置换,所以相当于只需枚举每个环的两个状态. 主要是复杂度分析这里: 一元环:不存在 二元环:特判保平安 三元环:不存 ...

  4. loj 6043「雅礼集训 2017 Day7」蛐蛐国的修墙方案

    loj 爆搜? 爆搜! 先分析一下,因为我们给出的是一个排列,然后让\(i\)给\(p_i\)连边,那么我们一定会得到若干个环,最后要使得所有点度数为1,也就是这些环有完备匹配,那么最后一定全是偶环. ...

  5. 「雅礼集训 2017 Day7」事情的相似度

    「雅礼集训 2017 Day7」事情的相似度 题目链接 我们先将字符串建后缀自动机.然后对于两个前缀\([1,i]\),\([1,j]\),他们的最长公共后缀长度就是他们在\(fail\)树上对应节点 ...

  6. 「雅礼集训 2017 Day7」跳蚤王国的宰相(树的重心)

    题面 来源 「 雅 礼 集 训 2017 D a y 7 」 跳 蚤 王 国 的 宰 相   传 统 2000   m s 1024   M i B {\tt「雅礼集训 2017 Day7」跳蚤王国的 ...

  7. 【LOJ 6041】「雅礼集训 2017 Day7」事情的相似度

    Description 人的一生不仅要靠自我奋斗,还要考虑到历史的行程. 历史的行程可以抽象成一个 01 串,作为一个年纪比较大的人,你希望从历史的行程中获得一些姿势. 你发现在历史的不同时刻,不断的 ...

  8. 【刷题】LOJ 6041 「雅礼集训 2017 Day7」事情的相似度

    题目描述 人的一生不仅要靠自我奋斗,还要考虑到历史的行程. 历史的行程可以抽象成一个 01 串,作为一个年纪比较大的人,你希望从历史的行程中获得一些姿势. 你发现在历史的不同时刻,不断的有相同的事情发 ...

  9. LOJ #6041. 「雅礼集训 2017 Day7」事情的相似度

    我可以大喊一声这就是个套路题吗? 首先看到LCP问题,那么套路的想到SAM(SA的做法也有) LCP的长度是它们在parent树上的LCA(众所周知),所以我们考虑同时统计多个点之间的LCA对 树上问 ...

随机推荐

  1. Python报错:UnicodeEncodeError 'gbk' codec can't encode character

    今天在使用Python文件处理写网络上爬取的文件的时候,遇到了错误:UnicodeEncodeError: ‘gbk’ codec can’t encode character ‘\xa0’ in p ...

  2. MAYA删除不干净

    AUTODESK系列软件着实令人头疼,安装失败之后不能完全卸载!!!(比如maya,cad,3dsmax等).有时手动删除注册表重装之后还是会出现各种问题,每个版本的C++Runtime和.NET f ...

  3. [转]jQuery页面滚动图片等元素动态加载实现

    本文转自:http://www.zhangxinxu.com/wordpress/?p=1259 一.关于滚动显屏加载 常常会有这样子的页面,内容很丰富,页面很长,图片较多.比如说光棍节很疯狂的淘宝商 ...

  4. [Android]JsonObject解析

    android和服务器进行交互的时候往往会有数据的传输,而数据中有一种类型就是Json型,这两天在研究API接口的问题,服务器返回的数据类型都是Json型的.例如: 1.接收到的json字符串分为两种 ...

  5. & 和nohup使用

    " & "的使用  将工作丢到背景(这里指的背景并非是系统的背景,指的是在终端模式下,可以避免ctrl+c中断的一个情景)中去执行(但是如果终端关闭时,程序也就退出了,这时 ...

  6. php验证码处理

    //基本步骤 1,先创建一张指定宽度和高度的一张验证码图片 imagecreatetruecolor() 2,给验证码图片添加背景颜色 和文字颜色 imagecolorallocate() 3, 在指 ...

  7. 最小白的webpack+react环境搭建

    本文也同步发表在我的公众号“我的天空” 从零开始,用最少的配置.最少的代码.最少的依赖来搭建一个最简单的webpack+react环境. 最近在玩webpack+react+移动端,那么第一步自然是搭 ...

  8. 从零开始的全栈工程师——js篇2.20(事件对象 冒泡与捕获)

    一.复习 面向对象 1)单例模式 2)工厂模式 3)构造函数 ①类js天生自带的类 基类object function array number math boolean date regexp st ...

  9. (生产)js-base64 - 转码

    参考:https://github.com/dankogai/js-base64 安装 $ npm install --save js-base64 使用 var Base64 = require(' ...

  10. base标签

    我们扒取到网站源码很多时候发现路径是采用相对路径,这时候我们就需要采用base标签了,用法非常简单, <base href="我们扒取网站的域名"/> 这时相对路径就相 ...