括号序列(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. C++目录

    C++ lambda表达式 C++中如何设计一个类只能在堆或者栈上创建对象,面试题 C++之STL总结精华笔记 指针强制类型转换的理解 关于指针类型和指针类型转换的理解 C++继承种类 C++ 单例模 ...

  2. 考研路茫茫——空调教室HDU2242(Tarjan缩点)

    题意:http://acm.hdu.edu.cn/showproblem.php?pid=2242 给你一个图,问你缩完点树上割边的做小绝对值差. 思路: 这题核算起来整整做了我一天(即24个小时)! ...

  3. Photon Server 实现注册与登录(四) --- 服务端响应登陆和注册

    前面已经整理过了服务端代码,MyGameServer.cs 和 ClientPeer.cs 对请求和响应进行了拆分.接下来处理对前端的响应 一.响应登陆请求 之前整理中,响应前端请求主要在类Clien ...

  4. 【Python基础】05_Python中的while循环

    1.程序的三大流程介绍 顺序 —— 从上到下,顺序执行 分支 —— 根据条件判断,决定代码的分支 循环 —— 让特定代码执行 2.while 基本语法 while 条件(判断 计数器 是否达到 目标次 ...

  5. Python 【函数】

    函数 内置函数print() input() len() type() ... print('Hello World') 函数 参数 定义函数def greet(name): print(name+' ...

  6. STM32 USB Virtual COM

    STM32 USB Virtual COM USB转串口的功能实现   这次讲的是如何实现USB转串口功能的实现.首先看看工程的布局吧: 我们主要要介绍的文件的在USB_User这个组文件.从上面的截 ...

  7. HDU5124lines题解-堆+贪心的一个新方法

    题目链接 https://cn.vjudge.net/problem/HDU-5124 胡扯 感觉说新方法好像有点不太好,但是翻了十几篇博客都是清一色离散化之类的... 为什么会做这道题呢?因为前几天 ...

  8. Spring事务的配置、参数详情及其原理介绍(Transactional)

    Spring 事务管理分为编程式和声明式的两种方式.编程式事务指的是通过编码方式实现事务:声明式事务基于 AOP,将具体业务逻辑与事务处理解耦.声明式事务管理使业务代码逻辑不受污染, 因此在实际使用中 ...

  9. Hexo NexT主题内加入动态背景

    主题内新添加内容 _layout.swig 找到themes\next\layout\_layout.swig文件,添加内容:在<body>里添加: 1 2 3 <div class ...

  10. CHD-5.3.6集群上Flume的文件监控

    收集hive的log     hive的运行日志:    /home/hadoop/CDH5.3.6/hive-0.13.1-cdh5.3.6/log/hive.log * memory *hdfs  ...