topcoder srm 688 div1 -3
problem1 link
首先去掉原串中已经配对的括号,那么剩下的括号序列是以下情况:(1)空串;(2)))));(3)((((;(4)))))((。第一种情况不需要处理。对于第三种情况和第四种情况,都可以将其变成第二种情况。第二种情况只需要对前一半做操作即可。另外,每次操作的时候不会影响已经删掉的匹配的串。
problem2 link
(1)首先,如果$[x,y_{1}],[x,y_{2}],y_{1}< y_{2}$都要是匹配的,那么有$[x,y_{1}],[y_{1}+1,y_{2}]$之间要分别匹配。
(2)其次,如果$[x_{1},y_{1}],[x_{2},y_{2}]$都要匹配,$x_{1}<x_{2}<y_{1}<y_{2}$,那么$[x_{1},x_{2}-1],[x_{2},y_{1}],[y_{1}+1,y_{2}]都要匹配$
经过这样的处理,最后所有匹配的区间可能会有包含的关系,然后没有其他相交关系。所以可以按照区间长度排序,一个区间一个区间进行处理。每个区间都相等于一个小的串(对于包含小区间的大区间不需要考虑已经处理的小区间,只需要考虑除了小区间外其他的部分匹配)。对于一个串$T$,定义$f(T)$表示将$T$变成匹配最少的修改数,这个修改指的是单独把左括号改成右括号或右括号改成左括号的次数,而不是交换。最后的答案其实是重复了一半,除以2即可。还有一个问题是有可能所有考虑的范围内的左括号数过于多,以至于在未考虑区间根本没有足够的右括号可以交换,这种情况是无解的。
problem3 link
这里有一个贪心的思路。
code for problem1
#include <algorithm>
#include <queue>
#include <string>
#include <vector> class ParenthesesDiv1Easy {
public:
std::vector<int> correct(std::string s) {
int n = static_cast<int>(s.size());
if (n % 2 == 1) {
return {-1};
}
return Dfs(s);
} std::vector<int> Dfs(std::string &s) {
int n = static_cast<int>(s.size());
std::deque<int> st;
for (int i = 0; i < n; ++i) {
if (s[i] == '(') {
st.push_back(i);
} else if (!st.empty() && s[st.back()] == '(') {
st.pop_back();
} else {
st.push_back(i);
}
}
if (st.empty()) {
return {};
}
std::vector<int> ans; for (size_t i = 0; i < st.size(); ++i) {
if (s[st[i]] == '(') {
int L = st[i];
int R = st.back();
ans.push_back(L);
ans.push_back(R);
Flip(s, L, R);
auto r = Dfs(s);
for (int x : r) {
ans.emplace_back(x);
}
return ans;
}
}
ans.push_back(st.front());
ans.push_back(*(st.begin() + st.size() / 2 - 1));
return ans;
} void Flip(std::string &s, int L, int R) {
std::reverse(s.begin() + L, s.begin() + R + 1);
for (int i = L; i <= R; ++i) {
if (s[i] == '(')
s[i] = ')';
else
s[i] = '(';
}
}
};
code for problem2
#include <algorithm>
#include <string>
#include <vector> class ParenthesesDiv1Medium {
public:
int minSwaps(const std::string &s, const std::vector<int> &L,
const std::vector<int> &R) {
int n = static_cast<int>(s.size());
int m = static_cast<int>(L.size()); std::vector<int> inside(n);
for (int i = 0; i < m; ++i) {
++inside[L[i]];
if (R[i] + 1 < n) {
--inside[R[i] + 1];
}
}
for (int i = 1; i < n; ++i) {
inside[i] += inside[i - 1];
} std::vector<std::vector<int>> ends(n);
for (int i = 0; i < m; ++i) {
ends[L[i]].emplace_back(R[i]);
}
std::vector<std::pair<int, int>> requests;
for (int i = 0; i < n; ++i) {
if (ends[i].empty()) {
continue;
}
std::sort(ends[i].begin(), ends[i].end());
ends[i].erase(std::unique(ends[i].begin(), ends[i].end()), ends[i].end()); for (size_t j = 1; j < ends[i].size(); ++j) {
ends[ends[i][j - 1] + 1].emplace_back(ends[i][j]);
}
ends[i].resize(1);
int x = ends[i][0];
for (int j = n - 1; j > i; --j) {
if (!ends[j].empty() && ends[j].back() >= ends[i][0]) {
x = min(x, j - 1);
}
}
if (x < ends[i][0]) {
ends[x + 1].emplace_back(ends[i][0]);
ends[i][0] = x;
}
requests.emplace_back(i, ends[i][0]);
} int ans = 0;
std::sort(requests.begin(), requests.end(),
[&](const std::pair<int, int> &a, const std::pair<int, int> &b) {
int ll = a.second - a.first;
int rr = b.second - b.first;
return ll != rr ? ll < rr : a.first < b.first;
});
std::string cs = s;
for (const auto &e : requests) {
int ll = e.first;
int rr = e.second;
std::string cur_s;
for (int j = ll; j <= rr; ++j) {
if (cs[j] != '*') {
cur_s += cs[j];
cs[j] = '*';
}
}
int c = Compute(cur_s);
if (c == -1) {
return -1;
}
ans += c;
}
if (total_left > total_len) {
ans += total_left - total_len;
} else {
ans += abs(total_right - total_len);
}
for (int i = 0; i < n; ++i) {
if (inside[i] == 0) {
if (s[i] == ')') {
--total_left;
} else {
--total_right;
}
}
}
if (total_left > total_len || total_right > total_len) {
return -1;
}
return ans / 2;
}
int Compute(const std::string &s) {
int n = static_cast<int>(s.size());
if (n % 2 == 1) {
return -1;
}
if (n == 0) {
return 0;
}
auto Update = [&](int &x, int y) {
if (x == -1 || x > y) {
x = y;
}
};
std::vector<std::vector<int>> dp(n, std::vector<int>(n + 1, -1));
dp[0][1] = s[0] == ')';
for (int i = 1; i < n; ++i) {
for (int j = 0; j <= i; ++j) {
if (dp[i - 1][j] == -1) {
continue;
}
if (s[i] == '(') {
Update(dp[i][j + 1], dp[i - 1][j]);
if (j > 0) {
Update(dp[i][j - 1], dp[i - 1][j] + 1);
}
} else {
if (j > 0) {
Update(dp[i][j - 1], dp[i - 1][j]);
}
Update(dp[i][j + 1], dp[i - 1][j] + 1);
}
}
}
for (char x : s) {
if (x == '(') {
++total_left;
} else {
++total_right;
}
}
total_len += n / 2;
return dp[n - 1][0];
} int total_left = 0;
int total_right = 0;
int total_len = 0;
};
code for problem3
#include <string> class ParenthesesDiv1Hard {
public:
int minCost(const std::string &s) {
int len = static_cast<int>(s.size());
std::string red, blue;
int r_num = 0, b_num = 0;
for (int i = 0; i < len; ++i) {
if (s[i] == '(') {
if (r_num == b_num) {
++r_num;
red += s[i];
} else {
++b_num;
blue += s[i];
}
} else {
if (r_num > b_num) {
red += s[i];
--r_num;
} else if (b_num == 0) {
return -1;
} else {
blue += s[i];
--b_num;
}
}
}
if (r_num != 0 || b_num != 0) {
return -1;
}
return Score(red).second + Score(blue).second;
} std::pair<int, int> Score(const std::string &s) {
int left = 0;
for (size_t i = 0; i < s.size(); ++i) {
if (s[i] == '(') {
++left;
} else if (--left == 0) {
auto score1 = Score(s.substr(1, i - 1));
auto score2 = Score(s.substr(i + 1));
int depth = std::max(score1.first + 1, score2.first);
int score = score1.second + (score1.first + 1) * (score1.first + 1) +
score2.second;
return {depth, score};
}
}
return {0, 0};
}
};
topcoder srm 688 div1 -3的更多相关文章
- Topcoder SRM 643 Div1 250<peter_pan>
Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...
- Topcoder Srm 726 Div1 Hard
Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...
- topcoder srm 714 div1
problem1 link 倒着想.每次添加一个右括号再添加一个左括号,直到还原.那么每次的右括号的选择范围为当前左括号后面的右括号减去后面已经使用的右括号. problem2 link 令$h(x) ...
- topcoder srm 738 div1 FindThePerfectTriangle(枚举)
Problem Statement You are given the ints perimeter and area. Your task is to find a triangle wi ...
- Topcoder SRM 602 div1题解
打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...
- Topcoder SRM 627 div1 HappyLettersDiv1 : 字符串
Problem Statement The Happy Letter game is played as follows: At the beginning, several players ...
- Topcoder SRM 584 DIV1 600
思路太繁琐了 ,实在不想解释了 代码: #include<iostream> #include<cstdio> #include<string> #include& ...
- TopCoder SRM 605 DIV1
604的题解还没有写出来呢.先上605的. 代码去practice房间找. 说思路. A: 贪心,对于每个类型的正值求和,如果没有正值就取最大值,按着求出的值排序,枚举选多少个类型. B: 很明显是d ...
- topcoder srm 575 div1
problem1 link 如果$k$是先手必胜那么$f(k)=1$否则$f(k)=0$ 通过对前面小的数字的计算可以发现:(1)$f(2k+1)=0$,(2)$f(2^{2k+1})=0$,(3)其 ...
随机推荐
- VS基本学习之(变量与常量)
一.变量与常量 1) 变量 由(定义+赋值+取值组成) 变量的命名规则: ① 变量名组成:字母 数字 下划线 @ 汉字 ② 首字母只能用:字母 下划线 @ 汉字(不能是数字 ...
- struts2.0自定义类型转换
在Struts2.0框架中内置了类型转换器,可以很方便的实现在八大数据类型.Date类型之间的自动转换:此外也可以根据自己的需求自定义数据转换类.如下: 首先看一下项目工程中的目录 1.在新建的web ...
- Python记录5:函数1
函数 ''' 1. 什么是函数 在程序中具备某一功能的工具->函数 函数的使用必须遵循原则: 先定义 后调用 函数分为两大类: 1 ...
- Unity shader学习之阴影
Unity阴影采用的是 shadow map 的技术,即把摄像机放到光源位置上,看不到的地方就有阴影. 前向渲染中,若一光源开启了阴影,Unity会计算它的阴影映射纹理(shadow map),它其实 ...
- Python全栈-异常处理
一.异常 1.异常的定义 异常是错误发生的信号,程序一旦出错就会抛出错误信息,如果不及时处理就会程序就会随之停止运行 异常有三部分组成: 1)异常类型 2)异常追踪 3)异常的值 2.异常的分类 1) ...
- 说说html 的<!DOCTYPE>声明&标准模式与兼容模式
我们都知道<!DOCTYPE>声明位于文档的最前面,处于<html>标签之前. <!DOCTYPE>声明不是html标签,它的作用:告知web浏览界面应该使用哪个h ...
- C#操作XML方法详解
using System.Xml; //初始化一个xml实例 XmlDocument xml=new XmlDocument(); //导入指定xml文件 xml.Load(path); xml. ...
- wifi pj WiFiPhisher 安装使用
1.安装kali linux: https://blog.csdn.net/qq_42545206/article/details/82788119 https://www.kali.org/down ...
- 最小二乘法的Java实现
最小二乘法原理十分简单,这里不再赘述.对于预测公式y' = a * x + b,最优解如下 double a = Sxy / Sxx; double b = yAvg - a * xAvg; doub ...
- 使用SpringBoot的优势。
Spring Boot 让开发变得更简单 Spring Boot 对开发效率的提升是全方位的,我们可以简单做一下对比: 在没有使用 Spring Boot 之前我们开发一个 web 项目需要做哪些工作 ...