括号序列(bracket)

Time Limit:1000ms   Memory Limit:128MB

题目描述

LYK有一个括号序列,但这个序列不一定合法。

一个合法的括号序列如下:

()是合法的括号序列。

若A是合法的括号序列,则(A)是合法的括号序列。

若A和B分别是合法的括号序列,则AB是合法的括号序列。

LYK想通过尽可能少的操作将这个不一定合法的括号序列变成合法的括号序列。一次修改操作是将某个字符变成另一个字符。

你能帮帮它吗?

输入格式(bracket.in)

一行一个字符串S。

输出格式(bracket.out)

一个数表示最少修改次数。

输入样例

()))

输出样例

1

样例解释

将第二个字符修改成(即可。

数据范围

对于30%的数据|S|<=10。

对于60%的数据|S|<=1000。

对于100%的数据|S|<=100000。且|S|是偶数。

思路:

  从左往右扫过来遇到一个")",观察之前有没有"(",如果有就抵消掉,如果没有的话就变成"("--->X

  如果我们一直这么做,扫完整个字符串之后,最终一定匹配完后剩下一堆左括号--->Y
  最后ans就是X+Y/2

上代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std; const int Ma = ;
char q[Ma]; struct MyStack { //手写栈
int top;
char stack[Ma];
MyStack () { top=; }
void pop() { top--; }
char push(char x) { stack[++top]=x; }
} st; int main() {
freopen("bracket.in","r",stdin);
freopen("bracket.out","w",stdout);
scanf("%s",q);
int ans=,n=strlen(q);
for(int i=; i<n; ++i) {
if(q[i]=='(')
st.push('(');
else {
if(st.top> && q[i]==')')
st.pop();
else {
st.push('(');
ans++;
}
}
}
ans+=st.top>>;
printf("%d",ans);
return ;
}

My

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <cstring>
using namespace std; char s[];
int i,p,o,ans; int main() {
freopen("bracket.in","r",stdin);
freopen("bracket.out","w",stdout);
scanf("%s",s);
p=strlen(s);
for (i=; i<p; i++) {
if (s[i]==')') {
if (o==) {
o++;
ans++;
} else
o--;
} else
o++;
}
cout<<ans+o/;
return ;
}

std


公交车(bus)

Time Limit:1000ms   Memory Limit:128MB

题目描述

LYK在玩一个游戏。

有k群小怪兽想乘坐公交车。第i群小怪兽想从xi出发乘坐公交车到yi。但公交车的容量只有M,而且这辆公交车只会从1号点行驶到n号点。

LYK想让小怪兽们尽可能的到达自己想去的地方。它想知道最多能满足多少小怪兽的要求。

当然一群小怪兽没必要一起上下车,它们是可以被分开来的。

输入格式(bus.in)

第一行三个数k,n,M。

接下来k行每行3个数xi,yi和ci。其中ci表示第i群小怪兽的小怪兽数量。

输出格式(bus.out)

一个数表示最多有多少只小怪兽能满足要求。

输入样例

3 5 3

1 3 4

3 5 2

1 5 3

输出样例

5

样例解释

第一群的3只小怪兽在1号点上车,并在3号点下车。

第二群的2只小怪兽在3号点上车,5号点下车。

数据范围

对于30%的数据小怪兽的总数不超过10只,n<=10。

对于另外30%的数据k,n<=1000。

对于100%的数据1<=n<=20000,1<=k<=50000,1<=M<=100,1<=ci<=100,1<=xi<yi<=n。

思路:

  1.所有线段根据右端点进行判断,枚举每一个区间,能取就取。
  2.维护一个f数组,f[i]表示这个时刻 车上已经做了多少只怪兽了(若[x,y]为z)

for(int i=x; i<y; ++i) Max=max(Max,f[i]);
--->t=min(z,M-Max)
for (int i=X; i<Y; i++) f[i]+=t;
--->ans+=t
cout<<ans;

  需要维护:
    1.区间+
    2.区间查询最大值
  固应该可以使用线段树 (O(klgn))

上代码:

//听说贪心只能过样例...看来应该是真的...
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std; const int Ma = ;
const int Na = ;
//lastc 当前在车上的怪兽数
//nxt 接下来应该枚举到的怪兽的id
//sdown 当前枚举到的点到达应该下车的位置下车的数
int k,n,M,lastc,nxt=,sdown,ans;
//Dd[] 储存上了车的怪兽在哪里下车
//Ss[] 记录在哪个点,满足了哪些怪兽的需求
int Dd[Na],Ss[Na];
struct GG {
int op,ed,cnt;
//可能这里有点问题...
bool operator < (const GG &qwq) const {
if(op==qwq.op && ed==qwq.ed)
return cnt > qwq.cnt;
else {
if(op==qwq.op && ed!=qwq.ed)
return ed < qwq.ed;
else return op < qwq.op;
}
}
}id[Ma]; int main() {
freopen("bus.in","r",stdin);
freopen("bus.out","w",stdout);
scanf("%d%d%d",&k,&n,&M);
for(int i=; i<=k; ++i)
scanf("%d%d%d",&id[i].op,&id[i].ed,&id[i].cnt);
sort(id+, id+k+);
for(int i=; i<=n; ++i) { //枚举n号点
lastc+=Dd[i]; //先让能下车的下车
for(int j=nxt; j<=k; ++j) { //枚举怪兽群
if(id[j].op>i) break; //对当前的i点是没有用处的,直接break
nxt++; //更新接下来应该搞哪一堆怪兽
sdown=id[j].cnt; //记录上下车数
if(sdown+lastc>M) //超载
sdown=M-lastc;
Dd[id[j].ed]-=sdown;
Ss[i]+=sdown;
lastc+=sdown;
}
}
for(int i=; i<=n; ++i)
ans+=Ss[i];
printf("%d",ans);
return ;
}
/*
5 5 3
1 5 3
1 3 4
3 5 2
3 4 1
4 5 5(正)
/----------------/
5 5 7
1 5 6
1 2 1
1 3 3
2 4 4
4 5 9(误)
*/

瞎贪心的20分

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std; const int c1 = ;
const int c2 = ;
const int c3 = ;
int tree[c3+][],n,m,c,i,MIN,ans;
struct node {
int x,y,z;
} A[]; int cmp(node i,node j) {
return i.y<j.y;
} void Update(int k) {
tree[k<<][]+=tree[k][];
tree[k<<|][]+=tree[k][];
tree[k<<][]+=tree[k][];
tree[k<<|][]+=tree[k][];
tree[k][]=;
} void work(int root,int l,int r,int k) {
if (l==tree[root][] && r==tree[root][]) {
tree[root][]+=k;
tree[root][]+=k;
return;
}
Update(root);
int mid=(tree[root][]+tree[root][])>>;
if (l<=mid) work(root<<,l,min(mid,r),k);
if (r>mid) work(root<<|,max(mid+,l),r,k);
tree[root][]=min(tree[root<<][],tree[root<<|][]);
} int find(int root,int l,int r) {
if (l==tree[root][] && r==tree[root][]) return tree[root][];
Update(root);
int mid=(tree[root][]+tree[root][])>>,p=c2,q=c2;
if (l<=mid) p=find(root<<,l,min(mid,r));
if (r>mid) q=find(root<<|,max(mid+,l),r);
return min(p,q);
} int main() {
// freopen("bus.in","r",stdin);
// freopen("bus.out","w",stdout);
scanf("%d%d%d",&n,&m,&c);
for (i=c1+; i<=c3; i++) tree[i][]=tree[i][]=i;
for (i=c1; i>=; i--) {
tree[i][]=tree[i<<][];
tree[i][]=tree[i<<|][];
}
work(,+c1,m+c1,c);
for (i=; i<=n; i++) {
scanf("%d%d%d",&A[i].x,&A[i].y,&A[i].z);
A[i].y--;
}
sort(A+,A+n+,cmp);
for (i=; i<=n; i++) {
MIN=find(,A[i].x+c1,A[i].y+c1);
if (MIN>A[i].z) {
work(,A[i].x+c1,A[i].y+c1,-A[i].z);
ans+=A[i].z;
} else {
work(,A[i].x+c1,A[i].y+c1,-MIN);
ans+=MIN;
}
}
cout<<ans;
return ;
}

正解

#include <cstdio>
#include <algorithm>
#define INF 0x7fffffff
using namespace std; const int M = ;
int k,n,m,ans,p[M];
struct node {
int op,ed,id;
bool operator < (const node &qwq) const {
return ed < qwq.ed;
return op < qwq.ed;
}
}e[M]; int main() {
scanf("%d%d%d",&k,&n,&m);
for(int i=; i<=k; i++)
scanf("%d%d%d",&e[i].op,&e[i].ed,&e[i].id);
sort(e+,e++k);
for(int i=; i<=k; i++) {
if(e[i].ed>n) break;
if(p[e[i].op]>=m) continue;
int minn=INF;
for(int j=e[i].op; j<=e[i].ed; j++) {
minn=min(m-p[j],minn);
if(minn<=) break;
}
if(minn>) {
if(minn>=e[i].id) {
for(int j=e[i].op; j<e[i].ed; j++)
p[j]+=e[i].id;
ans+=e[i].id;
}
else {
for(int j=e[i].op; j<e[i].ed; j++)
p[j]+=minn;
ans+=minn;
}
}
}
printf("%d\n",ans);
return ;
}

不用线段树的贪心


解谜游戏(puzzle)

Time Limit:1000ms   Memory Limit:128MB

题目描述

LYK进了一家古董店,它很想买其中的一幅画。但它带的钱不够买这幅画。

幸运的是,老板正在研究一个问题,他表示如果LYK能帮他解出这个问题的话,就把这幅画送给它。

老板有一个n*m的矩阵,他想找一个和最大的子矩阵,这个子矩阵可以由四个参数x,y,x2,y2(1<=x<=x2<=n,1<=y<=y2<=m)来表示,表示一个左上角为(x,y),右下角为(x2,y2)的矩阵。

为了让游戏更加有趣,老板给了一个常数P,他想将原来这个矩阵中恰好一个数变为P,使得这个矩阵的最大的子矩阵尽可能大。

老板想知道这个最大值是多少。

你能帮帮LYK吗?

输入格式(puzzle.in)

第一行三个数n,m,P。

接下来n行,每行m个数ai,j描述整个矩阵。

输出格式(puzzle.out)

输出一个数表示答案。

输入样例

3 3 3

-100 3 3

3 -4 3

3 3 3

输出样例

20

样例解释

改变左上角那个数。

数据范围

对于20%的数据n,m<=10。

对于40%的数据n,m<=25。

对于60%的数据n,m<=50。

对于80%的数据n,m<=100。

对于100%的数据1<=n,m<=300,|P|,|ai,j|<=1000。

思路:

  1.枚举左上角 n^2 枚举右下角n^2 枚举修改的数 n^2 求和 n^2 -> n^8
  2.求一个矩阵和,可以通过矩阵前缀和做到O(1)
    枚举左上角 n^2 枚举右下角n^2 枚举修改的数 n^2 -> n^6
  3.预处理出每个矩阵的最小值是多少。 n^4
    枚举左上角 n^2 枚举右下角n^2 修改的数已知(修改最小的或者不修改) -> n^4

  4.n,m<=300
    假如我们不要求修改数,查询最大子矩阵
    有n个数,查询最大子段和 O(n)

for (i=; i<=n; i++) f[i]=max(f[i-]+a[i],a[i]);
//max{f[i]} = 最大子段和

    要求我们修改数
      修改的数一定是最小的那个数。

//f[i][0]:以i结尾并且没有数被修改过的最大和
//f[i][1]:以i结尾并且有数被修改过的最大和 //a[i] 第i列的和
for (int i=; i<=n; i++)
{
f[i][]=max(f[i-][]+a[i],a[i]);
f[i][]=max(f[i-][]+a[i],f[i-][]+a[i]-MIN[i]+P,a[i]-MIN[i]+P);
}
//最后max{f[?][0/1]} 是答案

注意题目要求是:

    恰好改变一个数

上代码:

#include <iostream>
#include <cstdio>
using namespace std; const int M = ;
int n,m,p,Max=-,Min=0x7fffffff;
int Mi,Mj,Mk,Ml;
int map[M][M],sum[M][M];
int jz[M][M][M][M]; int main() {
freopen("puzzle.in","r",stdin);
freopen("puzzle.out","w",stdout);
scanf("%d%d%d",&n,&m,&p);
for(int i=; i<=n; ++i)
for(int j=; j<=m; ++j) {
scanf("%d",&map[i][j]);
sum[i][j]=sum[i-][j]+sum[i][j-]-sum[i-][j-]+map[i][j];
}
for(int i=; i<=n; ++i)
for(int j=; j<=m; ++j)
for(int k=n; k>i; --k)
for(int l=m; l>j; --l)
jz[i][j][k][l]=sum[k][l]-sum[i][l]-sum[k][j]+sum[i][j];
for(int i=; i<=n; ++i)
for(int j=; j<=m; ++j)
for(int k=i+; k<=n; ++k)
for(int l=j+; l<=m; ++l)
if(jz[i][j][k][l]>Max)
Max=jz[i][j][k][l],Mi=i,Mj=j,Mk=k,Ml=l;
for(int i=Mi; i<=Mk; ++i)
for(int j=Mj; j<=Ml; ++j)
if(map[i][j]<Min)
Min=map[i][j];
printf("%d",jz[Mi][Mj][Mk][Ml]-Min+p);
return ;
}

瞎搞20

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <assert.h>
using namespace std;
int n,m,a[][],MIN[],b[],dp[][],i,j,s[][],ans,P,k;
int main()
{
freopen("puzzle.in","r",stdin);
freopen("puzzle.out","w",stdout);
while (cin>>n)
{
ans=-;
scanf("%d%d",&m,&P); assert(<=n && n<= && <=m && m<= && -<=P && P<=);
for (i=; i<=n; i++)
for (j=; j<=m; j++) {scanf("%d",&a[i][j]); assert(-<=a[i][j] && a[i][j]<=); }
for (i=; i<=n; i++)
for (j=; j<=m; j++)
s[i][j]=s[i-][j]+a[i][j];
for (i=; i<=n; i++)
{
for (j=; j<=m; j++) MIN[j]=a[i][j];
for (j=i; j<=n; j++)
{
for (k=; k<=m; k++) MIN[k]=min(MIN[k],a[j][k]);
for (k=; k<=m; k++) b[k]=s[j][k]-s[i-][k]; dp[][]=-;
for (k=; k<=m; k++) dp[k][]=max(dp[k-][]+b[k],b[k]),dp[k][]=max(max(dp[k-][]+b[k],dp[k-][]+b[k]-MIN[k]+P),b[k]-MIN[k]+P);
for (k=; k<m; k++) ans=max(ans,max(dp[k][],dp[k][]));
if (i== && j==n)
{
ans=max(ans,dp[m][]); int sum=;
for (k=m; k>; k--) {sum+=b[k]; ans=max(ans,sum);}
} else
ans=max(ans,max(dp[m][],dp[m][]));
}
}
cout<<ans<<endl;
}
return ;
}

正解

北京清北 综合强化班 Day3的更多相关文章

  1. 2017.10.3北京清北综合强化班DAY3

    括号序列(bracket) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK有一个括号序列,但这个序列不一定合法. 一个合法的括号序列如下: ()是合法的 ...

  2. 2017.10.4北京清北综合强化班DAY4

    财富(treasure) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK有n个小伙伴.每个小伙伴有一个身高hi. 这个游戏是这样的,LYK生活的环境是以 ...

  3. 2017.10.7北京清北综合强化班DAY7

    1.计数 (count.cpp/c/pas) 时间限制:1s 内存限制:256MB [问题描述] 给出m个数a[1],a[2],…,a[m] 求1~n中有多少数不是a[1],a[2],…,a[m]的倍 ...

  4. 2017.10.6北京清北综合强化班DAY6

    题目大意:改变一个数的位置 把一个序列变成不下降序列 题解: 设置一个pre,如果破坏单调性,就把‘删除’这个.否则把pre修改为当前元素的值. 考试时这样得了90分,是因为我的做法只能过这样的数据 ...

  5. 2017.10.5北京清北综合强化班DAY5

    拼不出的数lost.in/.out/.cpp[问题描述]3 个元素的集合{5, 1,2} 的所有子集的和分别是0,1, 2, 3, 5, 6, 7, 8.发现最小的不能由该集合子集拼出的数字是4.现在 ...

  6. 2017.10.2北京清北综合强化班DAY2

    a[问题描述]你是能看到第一题的 friends呢.                                                —— hja世界上没有什么比卖的这 贵弹丸三还令人绝 ...

  7. 2017.10.1北京清北综合强化班DAY1

    a[问题描述]你是能看到第一题的 friends 呢.——hja何大爷对字符串十分有研究,于是天天出字符串题虐杀 zhx. 何大爷今天为字符串定义了新的权值计算方法.一个字符串 由小写字母组成,字符串 ...

  8. 北京清北 综合强化班 Day5

    T1 思路: 输入数据,sort一下, 如果a[i]>sum+1(前缀和) 那么sum+1就一定不会被拼出来, 然后输出即可. 上代码: #include <iostream> #i ...

  9. 北京清北 综合强化班 Day4

    财富(treasure) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK有n个小伙伴.每个小伙伴有一个身高hi. 这个游戏是这样的,LYK生活的环境是以 ...

随机推荐

  1. NIT校赛-- 雷顿女士与平衡树

    题意:https://ac.nowcoder.com/acm/contest/2995/E 给你一棵树,节点有权值,让你求所有路径max-min的和. 思路: 我们计算每个点的贡献,对于一个点,当它为 ...

  2. SHE姐妹建模记录

    中午11点54分,队长把MD5码提交上去在群里发了截图,我对着屏幕上刚检查完的论文,感觉整个人都轻松起来了,又有点恍惚,可能是这几天都没睡好觉.去楼下吃了顿饭,本来打算回来倒头就睡,睡到几点算几点,醒 ...

  3. 17.tmux相关

    Linux终端复用神器-Tmux使用梳理 Tmux是一个优秀的终端复用软件,类似GNU Screen,但来自于OpenBSD,采用BSD授权.使用它最直观的好处就是,通过一个终端登录远程主机并运行tm ...

  4. java-filter and listener

    Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层. 使用 Serv ...

  5. 第一章、web应用安全概论--web应用系统介绍--TCP/IP协议

    TCP/IP协议源于1969年,是国际互联网Internet采用的协议标准TCP/IP协议是一组通信协议的代名词,是由一系列协议组成的协议族,本身是指两个协议集:    TCP--传输控制协议    ...

  6. Python 运算符与数据类型

    Python 的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承.Py ...

  7. 牛客 203B tree(树形dp)

    大意: 给定树, 对于每个节点, 求包含该节点的连通子集数. 显然有$dp[x]=\prod (dp[y]+1), ans[x]=(\frac{ans[fa[x]]}{dp[x]+1}+1)dp[x] ...

  8. element-ui 中 table 鼠标悬停时背景颜色修改

    样式穿透: /deep/ .el-table tbody tr:hover>td { background-color: #颜色 }

  9. C#使用phantomjs,爬取AJAX加载完成之后的页面

    1.开发思路:入参根据apiSetting配置文件,分配静态文件存储地址,可实现不同站点的静态页生成功能.静态页生成功能使用无头浏览器生成,生成之后的字符串进行正则替换为固定地址,实现本地正常访问. ...

  10. 微信小程序上传图片更新图像

    解决思路: 1. 调用wx.chooseImage 选择图片 2.wx.uploadFile 上传图片 3.调用后台接口进行修改操作 修改原来的头像 wx.chooseImage({ success: ...