P6000 [CEOI2016] match

news/2025/12/7 12:38:53/文章来源:https://www.cnblogs.com/zloi-hhq/p/19317945

洛谷

对于暴力写法,我们很容易想到一个 \(O(n^2)\) 的暴力。

我们可以先从左到右枚举需要配对的字符,然后从后往前去找到一个合法且相同的字符配对。

对于怎样才算合法,我们通过此部分内部是否合法,以及前面是否有已选择的括号判断。

在括号本身是合法的情况下,我们处理右边是否合法,对于本身存在解的串,左边也必定合法,可以自己模拟证明。

那么我们还需要找到上一次配对的右端,从这里从后往前开始枚举。可以选择使用搜索,这样可以直接继承上一步的端点位置,直接开始枚举。

由于枚举位置较少,除了最后一个测试点都能过。

代码:

#include<bits/stdc++.h>
using namespace std;
char s[100005],ans[100005],p[100005];
bool f[100005];
int len,cnt;
signed main(){cin>>s+1;len=strlen(s+1);if(len%2==1){cout<<-1;return 0;}f[len+1]=1;for(int i=1;i<=len;i++){if(f[i])continue;bool flag=0;int w;for(int j=i+1;j<=len+1;j++){if(f[j]){w=j;break;}}for(int j=w-1;j>i;j--){if(cnt==0&&s[j]==s[i]){flag=1;ans[j]=')';f[j]=1;break;}if(!cnt||p[cnt]!=s[j])p[++cnt]=s[j];else cnt--;}if(!flag){cout<<-1;return 0;}ans[i]='(';}cout<<ans+1;return 0;
}

时间复杂度的瓶颈明显在于如何找到合适的配对。

第一种做法是哈希,我们使用字符串哈希记录下当前结点未配对的字符,若字符相同且两个点的字符相同,则可以组成合法的括号,直接二分得到配对即可。

代码:

#include<bits/stdc++.h>
#define ull unsigned long long
using namespace std;
const int base=131;
char s[100005],ans[100005];
int len,p[100005],top;
ull h[100005],b[100005];
vector<pair<ull,int>> e[30];
void init(){for(int i=len;i>=1;i--){if(top&&s[p[top]]==s[i])top--;else{p[++top]=i;h[top]=h[top-1]*base+s[i];}b[i]=h[top];e[s[i]-97].push_back({b[i],i});}if(top){cout<<-1;exit(0);}for(int i=0;i<26;++i)sort(e[i].begin(),e[i].end());
}
int find(int p,ull v,int x){int l=0,r=e[p].size(),ans;while(l<=r){int mid=l+r>>1;if(e[p][mid].first<v)l=mid+1;else if(e[p][mid].first>v)r=mid-1;else{if(e[p][mid].second>x)r=mid-1;else{l=mid+1;ans=e[p][mid].second;}}}return ans;
}
void dfs(int l,int r){if(l>r)return;ans[l]='(',ans[r]=')';if(r-l==1)return;int x=find(s[l]-97,b[l+1],r);ans[x]=')';dfs(l+1,x-1),dfs(x+1,r);
}
signed main(){cin>>s+1;len=strlen(s+1);init();dfs(1,len);cout<<ans+1;return 0;
}

第二种做法,考虑动态规划,设置 \(dp_{i,j}\) 表示以 \(i\) 为最右端,在一个符号为 \(j\) 且在此之后到 \(i\) 可以组成一个合法括号串的最大位置。

我们可以得到方程式:

\[dp_{i,j}=dp_{dp_{i-1,s_i-97}-1,j} \]

看似复杂实际上很简单,相当于连接了两个括号串。

然后怎么处理答案呢?

我们从暴力方法可以通过搜索得到范围,那么我们知道了右端点位置,就可以用右端点找到一个最靠右的点与左端点进行匹配。

代码:

#include<bits/stdc++.h>
using namespace std;
int len,p[100005],cnt,dp[100005][30];
char s[100005],ans[100005];
bool check(){for(int i=1;i<=len;i++){if(cnt&&p[cnt]==s[i]-'a')cnt--;else p[++cnt]=s[i]-'a';}if(cnt)return true;cnt=0;return false;
}
void dfs(int l,int r){if(l>r)return ;int tmp=dp[r][s[l]-97];ans[l]='(',ans[tmp]=')';dfs(l+1,tmp-1),dfs(tmp+1,r);
}
signed main(){cin>>s+1;len=strlen(s+1);if(check()){cout<<-1;return 0;}for(int i=1;i<=len;i++){for(int j=0;j<26;j++)if(dp[i-1][s[i]-97])dp[i][j]=dp[dp[i-1][s[i]-97]-1][j];dp[i][s[i]-97]=i;}dfs(1,len);cout<<ans+1;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/991382.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MultiButton移植记录

使用记录 使用PA0引脚,电路图如下,使用GPIO内部下拉。实际测试,很稳定,没有误触发,单击、双击、长按很稳定。移植记录复制multi_button.c和multi_button.h到工程中,实现GPIO的初始化、读取。void key_init(void)…

Hugging Face 论文页面功能指南

在飞速变化的研究世界中,紧跟最新进展至关重要。为帮助开发者与研究人员把握 人工智能 前沿动态,我们推出了 Daily Papers 页面。自上线以来,Daily Papers 已收录超过 1 万 篇由 AK 与社区研究者精选的高质量论文。…

北京上门回收老酒名酒茅台五粮液

您家里是否存放着一些陈年佳酿,或是亲友相赠却不知价值的名酒?它们或许静置于橱柜一角,或收藏于箱底,随着岁月流逝,其价值可能已悄然攀升。京城亚南酒业,立足北京多年,专注于老酒、名酒的专业上门回收服务,为您…

P5202 [USACO19JAN] Redistricting P

洛谷 首先我们设更赛牛为加一,荷斯坦牛为负一。 这样通过前缀和就可以得到这一组是否需要增加一。 设 \(dp_i\) 表示以 \(i\) 为末尾,最少的分区。 那么方程式就为: \[$ dp_i=dp_j+(pre_i-pre_j\le 0) $\]然而表达式…

详细介绍:数据结构5:二叉树

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Excel 公式

Excel 公式 Excel 要将 A1 和 B1 的数据拼接成 (A1,B1), 格式,公式如下: ="("&A1&","&B1&")," 公式拆解说明公式片段 作用说明"(" 固定开头文本,生成左半…

P10602 [CEOI 2009] Harbingers

洛谷 我们可以考虑使用动态规划来解决。 在线性情况下,我们可以直接将状态设为 \(dp_i\) 表示走到 \(i\) 号点的时候的最小路程。 可以得到状态转移方程: \[$ dp_i=\min(dp_j+(l_i-l_j)\times v_i+s_i) $\]其中 \(l_…

2025 Newest Autel BMW G-Chassis IMMO Add Key (1-Year License) for IM508/IM608/IM1/IM2

Solving BMW IMMO Programming Headaches: The 2025 Autel Solution for G-Chassis Vehicles For European and American BMW owners and mechanics, the challenge of adding keys or programming IMMO systems can f…

Go 1.25 发布:性能、器具与生态的全面进化

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

P6173 [USACO16FEB] Circular Barn P

洛谷 由于环非常难处理,但是这个数据范围又很小,所以很容易想到枚举一个谷仓的位置,然后以这个地点为起始点使用动态规划。 为了使转移方便,我这里选择了逆时针处理这样计算这一段奶牛的路程。 我们定义 \(dp_{i,j…

为数字文明奠基:论通译院-价值星图-叙事舞台架构作为价值实践的元操作系统

论文标题:为数字文明奠基:论通译院-价值星图-叙事舞台架构作为价值实践的元操作系统 摘要: 在价值多元且快速流变的数字时代,传统旨在寻求或定义一套普适、永恒价值规则的AI伦理与治理范式面临根本性困境。本文提出…

实用指南:OSG多视口与多通道渲染核心技术解析

实用指南:OSG多视口与多通道渲染核心技术解析2025-12-07 12:19 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: …

P8313 [COCI 2021/2022 #4] Izbori

洛谷 首先观察部分分,对于前两组部分分,可以直接暴力枚举左右端点。 对于第三组部分分,从前缀和的角度去思考,然后可以发现假设一个数字为正数,一个数字为负数,开桶进行统计,只要两种人数不打平即可。 代码: #…

汽车智能座舱软件、技术、分类介绍

汽车智能座舱软件介绍 一、OSI模型1、(CANH = 3.5V)- (CANL = 1.5V)= 2V 低电压,逻辑零,显性信号 2、(CANH = 2.5V)- (CANL = 2.5V)= 0V 高电压,逻辑一,隐形信号二、技术架构三、关键技术汽车智能座舱软…

2025 最新智能制造服务商 / 厂家 TOP5 评测!科技赋能 + 全周期服务权威推荐榜单发布,引领智慧工厂建设新生态

随着工业4.0进程的加速,智能制造已成为推动制造业转型升级的核心引擎。市场对专业智能制造解决方案的需求日益增长,对服务商的技术实力、行业经验与全周期服务能力提出了更高要求。本榜单基于技术创新力、行业适配性…

『NAS』在群晖部署图表绘制工具-Draw.io

点赞 + 关注 + 收藏 = 学会了整理了一个NAS小专栏,有兴趣的工友可以关注一下 👉 《NAS邪修》Draw.io 是一款免费开源的在线图表绘制工具,支持创建流程图、思维导图、UML 图等多种图表,提供跨平台使用和多格式导出…

CF762E Radio stations

Codeforces 很明显是一道偏序问题,我们先列出满足条件的台之间的关系。 \[\min(r_i,r_j)\ge|x_i-x_j| \]\[|f_i-f_j|\le k \]这看起来好像是两条式子,但是不能直接使用二维偏序解决,因为其中含有取最小值操作,所以…

grep 常用功能

grep 常用功能 检索服务器文件的 panic // 查找文件中包含 panic 的行,并要同时显示上下各 20 行,-A 代表显示匹配行之后的指定行数,-B 代表显示匹配行之前的指定行数。 grep -A 20 -B 20 "panic" daemon…

2025 最新工业自动化服务商 / 厂家 TOP5 评测!科技赋能 + 全周期服务权威榜单发布,引领智慧工厂建设新生态

随着工业4.0时代的深入推进,工业自动化已成为制造企业实现高效、智能、绿色生产的核心驱动力。本榜单基于技术创新能力、行业服务深度、全周期解决方案能力三大维度(德尔智慧新增“资产健康管理”维度),结合行业实…

2025 最新智慧工厂建设服务商/厂家 TOP5 评测!科技赋能+全周期服务权威推荐榜单发布,引领智能制造新生态

随着工业4.0浪潮的深入推进,智慧工厂建设已成为制造企业实现转型升级、提升核心竞争力的关键路径。本榜单基于技术创新力、行业适配性、服务覆盖度及全生命周期管理能力四大维度,结合行业发展趋势与客户实际应用反馈…