10.3 test solution.
来源:互联网 发布:console显示日志java 编辑:程序博客网 时间:2024/06/07 04:54
1.括号序列(bracket)
Time Limit:
1000ms
Memory Limit:
128MB
题目描述
LYK有一个括号序列,但这个序列不一定合法。
一个合法的括号序列如下:
()是合法的括号序列。
若A是合法的括号序列,则(A)是合法的括号序列。
若A和B分别是合法的括号序列,则AB是合法的括号序列。
LYK想通过尽可能少的操作将这个不一定合法的括号序列变成合法的括号序列。一次修改操作是将某个字符变成另一个字符。
你能帮帮它吗?
输入格式(bracket.in)
一行一个字符串
输出格式(bracket.out)
一个数表示最少修改次数。
输入样例
()))
输出样例
1
样例解释
将第二个字符修改成(即可。
数据范围
对于
对于
对于
solution
把字符串从左往右扫一遍,用一个计数器
x 存当前没有抵消掉的(
的数量如果是
(
,如果x=strlen(s)/2 ,那就ans++,x−− ,否则x++ 因为如果括号合法,那
(
和)
的数量肯定是strlen(s)/2 所以如果
(
的数量已经是strlen(s)/2 了,那就只能把他变成)
,变成)
以后,他肯定会抵消掉一个(
,所以如果x=strlen(s)/2 ,那就ans++,x−− 如果是
)
,如果x=0 ,那就ans++,x++ ,否则x−− 因为如果没有
(
给)
匹配,那就只能把他变成(
扫完以后,
ans 最后还要加上x/2 ,因为如果还有(
没有抵消,就需要把其中的一半变成)
,所以最后要加上x/2
code
- test AC code
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define MAXN 100010char s[MAXN];int main() { freopen("bracket.in","r",stdin); freopen("bracket.out","w",stdout); scanf("%s",s); int n=strlen(s); int ans=0,x=0; for(int i=0;i<n;i++) { if(s[i]=='(') { if(x==n/2) ans++,x--; else x++; } if(s[i]==')') { if(x==0) ans++,x++; else if(x<=n/2) x--; } } printf("%d",ans+x/2); fclose(stdin); fclose(stdout); return 0;}
2.公交车(bus)
Time Limit:
1000ms
Memory Limit:
128MB
题目描述
LYK在玩一个游戏。
有k群小怪兽想乘坐公交车。第
LYK想让小怪兽们尽可能的到达自己想去的地方。它想知道最多能满足多少小怪兽的要求。
当然一群小怪兽没必要一起上下车,它们是可以被分开来的。
输入格式(bus.in)
第一行三个数
接下来k行每行3个数
输出格式(bus.out)
一个数表示最多有多少只小怪兽能满足要求。
输入样例
3 5 31 3 43 5 21 5 3
输出样例
5
样例解释
第一群的3只小怪兽在1号点上车,并在3号点下车。
第二群的2只小怪兽在3号点上车,5号点下车。
数据范围
对于
对于另外
对于
solution
考虑经典的线段覆盖,是按右端点排序之后,能取就取
所以这些怪兽也是这样,按照右端点排序之后,能取就取,能过几个就过几个
上面那个贪心是正确的,亲测可以AC,
证明显然这样的话我们就需要知道在某个时刻
t ,有多少只小怪兽在车上所以维护一个数组
f[i] ,表示i 这个时刻有多少只小怪兽在车上所以对于排序之后的一个区间,我们可以写出下面的伪代码
for (int i=X; i<Y; i++) MAX=max(MAX,f[i]);//在这个区间里找最多有几只小怪兽t=min(Z,M-MAX);//M-MAX就是最少可以做多少只怪兽,for (int i=X; i<Y; i++) f[i]+=t;ans+=t
- 所以区间加区间求MAX就可以用数据结构来维护,线段树就好了
code
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;template<typename T>void input(T &x) { x=0; T a=1; register char c=getchar(); for(;c<'0'||c>'9';c=getchar()) if(c=='-') a=-1; for(;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0'; x*=a; return;}#define MAXK 50010#define MAXN 20010#define MAXM 110struct Data { int l,r,sum; Data(int l=0,int r=0,int sum=0): l(l),r(r),sum(sum) {} bool operator < (const Data &q) const { if(r!=q.r) return r<q.r; return l<q.l; }};Data mon[MAXK];struct Segment_Tree { int l,r,tag,Max;};Segment_Tree t[MAXN<<2];void updata(int now) { t[now].Max=max(t[now<<1].Max,t[now<<1|1].Max); return;}void build(int now,int l,int r) { t[now].l=l,t[now].r=r; if(l==r) { t[now].Max=0; return; } int mid=l+r>>1; build(now<<1,l,mid); build(now<<1|1,mid+1,r); updata(now); return;}void pushdown(int now) { int &d=t[now].tag; t[now<<1].tag+=d; t[now<<1|1].tag+=d; t[now<<1].Max+=d; t[now<<1|1].Max+=d; d=0; return;}void Modify(int now,int L,int R,int x) { int l=t[now].l,r=t[now].r; if(l==L&&R==r) { t[now].tag+=x; t[now].Max+=x; return; } if(t[now].tag) pushdown(now); int mid=l+r>>1; if(R<=mid) Modify(now<<1,L,R,x); else if(L>mid) Modify(now<<1|1,L,R,x); else { Modify(now<<1,L,mid,x); Modify(now<<1|1,mid+1,R,x); } updata(now); return;}int query(int now,int L,int R) { int l=t[now].l,r=t[now].r; if(l==L&&R==r) return t[now].Max; if(t[now].tag) pushdown(now); int mid=l+r>>1; if(R<=mid) return query(now<<1,L,R); else if(L>mid) return query(now<<1|1,L,R); else { int a=query(now<<1,L,mid), b=query(now<<1|1,mid+1,R); return max(a,b); }}int main() { int k,n,m; input(k),input(n),input(m); for(int i=1,x,y,c;i<=k;i++) { input(x),input(y),input(c); mon[i]=Data(x,y-1,c); } sort(mon+1,mon+k+1); build(1,1,n); int ans=0; for(int i=1,l,r,Max;i<=k;i++) { l=mon[i].l,r=mon[i].r; Max=min(mon[i].sum,m-query(1,l,r)); ans+=Max; Modify(1,l,r,Max); } printf("%d\n",ans); return 0;}
3.解谜游戏(puzzle)
Time Limit:
1000ms
Memory Limit:
128MB
题目描述
LYK进了一家古董店,它很想买其中的一幅画。但它带的钱不够买这幅画。
幸运的是,老板正在研究一个问题,他表示如果LYK能帮他解出这个问题的话,就把这幅画送给它。
老板有一个
为了让游戏更加有趣,老板给了一个常数
老板想知道这个最大值是多少。
你能帮帮LYK吗?
输入格式(puzzle.in)
第一行三个数
接下来
输出格式(puzzle.out)
输出一个数表示答案。
输入样例
3 3 3-100 3 33 -4 33 3 3
输出样例
20
样例解释
改变左上角那个数。
数据范围
对于
对于
对于
对于
对于
solution
要想会做这个题,首先要会求最大子矩阵
所以先说一下怎么求最大子矩阵
对于每一列,我们做一个前缀和,即
sum[i][j] 表示第i 行前j 列的和然后我们枚举子矩阵的左上角和右下角所在的行
这样问题就变成了最大字段和问题,用一张图来解释
因为我们预处理了
sum ,所以第i 行和第j 行第k 列的值就可以用sum[j][k]−sum[i−1][k] 来表示所以
i 和j 之间的每一列的和就变成了一个值,所以他们就构成了一个序列而我们要找的就是一个区间
[l,r] 使得区间的和最大,这就是赤裸裸的最大字段和问题因为求最大字段和的做法太多了,所以就不展开讲啦,推荐一篇blog
会求最大子矩阵之后,再想一个很显然贪心
在一个子矩阵中,修改矩阵中的最小值是最好的
所以我们每次加和都有两种决策,不修改和改最小值
然后利用这个修改一下最大子段和的
dp 就可以了f[i][0] 以i 结尾并且没有数被修改过的最大和f[i][1] 以i 结尾并且有数被修改过的最大和f[i][0] 显然就是最大子段和重点是
f[i][1] 怎么更新修改可能在
i 之前,那f[i][1] 就可以用f[i−1][1]+b[i] 更新,b[i] 表示第i 列的和修改可能就在
i ,那f[i][1] 就可以用f[i−1][0]+b[i]+P−Min[i] 更新,也就是改的话最大子矩阵的和会比不改多P−Min[i] ,Min 显然是用来存最小值的当然也有可能第
i 列的和修改以后比之前的和大,那这个时候f[i][1] 就可以用b[i]+P−Min[i] 更新所以综上所述
f[i][1]=max{f[i−1][1]+b[i],f[i−1][0]+b[i]+P−Min[i],b[i]+P−Min[i]} 但是题目中的要求是必须修改1个数,所以还要考虑一下最后答案怎么更新,具体见代码
code
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;template<typename T>void input(T &x) { x=0; T a=1; register char c=getchar(); for(;c<'0'||c>'9';c=getchar()) if(c=='-') a=-1; for(;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0'; x*=a; return;}#define MAXN 310#define MAXM 310int f[MAXM][2];int b[MAXM];int a[MAXN][MAXM];int sum[MAXN][MAXM];int Min[MAXM];int main() { int n,m,p; input(n),input(m),input(p); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { input(a[i][j]); sum[i][j]=sum[i-1][j]+a[i][j]; } int ans=-20001120; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) Min[j]=a[i][j]; for(int j=i;j<=n;j++) { for(int k=1;k<=m;k++) Min[k]=min(Min[k],a[j][k]); for(int k=1;k<=m;k++) b[k]=sum[j][k]-sum[i-1][k]; f[0][1]=-20001120; for(int k=1;k<=m;k++) { f[k][0]=max(f[k-1][0]+b[k],b[k]); f[k][1]=max(f[k-1][1]+b[k],max(f[k-1][0]+b[k]+p-Min[k],b[k]+p-Min[k])); } for(int k=1;k<m;k++) ans=max(ans,max(f[k][1],f[k][0])); if(i==1&&j==n) { ans=max(ans,f[m][1]); for(int k=m,sum=0;k>1;k--) { sum+=b[k]; ans=max(ans,sum); } } else ans=max(ans,max(f[m][1],f[m][0])); } } printf("%d\n",ans); return 0;}
- 10.3 test solution.
- 8.15 Test Problem Solution.
- 9.17 test solution.
- 9.18 test solution.
- 10.1 test solution.
- 10.2 test solution.
- 10.4 test solution.
- 10.5 test solution.
- 10.6 test solution.
- 10.7 test solution.
- 10.28 test solution.
- <<.net test automation Recipes a problem solution appoach
- 如何在solution中添加一个test case
- 如何在solution中添加一个test case
- Google Programming Test Problem SecretSum C++ 11 Solution
- Solution:
- solution
- test
- JavaScript中的 Date.parse(),Date.UTC().
- 数据结构实验之栈与队列六:下一较大值(二)
- [bzoj4653][离散化][线段树]区间
- Material 组件 card和button
- org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
- 10.3 test solution.
- hadoop的shell命令操作
- 数据结构实验之栈与队列四:括号匹配
- Python3教程
- Leetcode 336. Palindrome Pairs 给出一种遍历字符串回文子串中心的方法
- UVA 572 Oil Deposits
- 数据结构实验之栈与队列二:一般算术表达式转换成后缀式
- 永远追不上的人?
- fragment不会保留最后一个