51nod 1624 STL妙用+二分
2016-05-06 16:55
495 查看
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1624
这是算法马拉松一道题。当时想法方向是正确的可惜没有想到STL。
题意3*n的矩阵。。要走出一条取余最大路。。
看到3肯定是在这里做文章。。那么可以枚举第一行二分剩下的嘛。。
到这里思路都很清晰,但是考虑到如果不删除(删除当前节点不合法的走法,移动一下删一个)的话,二分就结果不一定正确了。。这就十分尴尬
赛后看题解可以 multiset来删除,当然也可以map了。。。这里就是经验的问题了
二分时候要注意一些地方,一个最优答案当然是靠近P-1了,那么枚举的x怎么靠近P-1呢,当然有两种方法,一是x+y靠近p-1,要么是x+y靠近2*p-1了。
然后在multiset里面二分即可。。
这里要学习stl的应用,自己根本没有领会到stl的精髓啊。。。蒟蒻加油!
#include <iostream>
#include <set>
#include <stdio.h>
#include <algorithm>
#include <fstream>
using namespace std;
const int maxn=100005;
long long n,p;
long long arr[3][maxn];
long long sum[3][maxn];
multiset<int> s;
int main()
{
scanf("%d%d",&n,&p);
for(int i=0;i<3;i++){
for(int j=0;j<n;j++){
scanf("%d",&arr[i][j]);
arr[i][j]=arr[i][j]%p;
}
}
sum[0][0]=arr[0][0]%p;
sum[0][1]=arr[0][1]%p;
sum[0][2]=arr[0][2]%p;
for(int i=0;i<3;i++){
for(int j=1;j<n;j++){
sum[i][j]=(sum[i][j-1]+arr[i][j])%p;
}
}
for(int j=0;j<n;j++){
s.insert(-((sum[1][j]+sum[2][n-1]-sum[2][j]+arr[2][j]+p+p)%p));
}
int ans=0;
int x;
multiset<int>::iterator it;
for(int i=0;i<n;i++){
it=s.lower_bound(-(p-1-(sum[0][i]-sum[1][i]+arr[1][i]+p+p)%p));
if(it!=s.end())
x=(sum[0][i]-sum[1][i]+arr[1][i]-*it+p+p)%p;
it=s.lower_bound(-(p+p-1-(sum[0][i]-sum[1][i]+arr[1][i]+p+p)%p));
if(it!=s.end())
x=max((sum[0][i]-sum[1][i]+arr[1][i]-*it+p+p)%p,(long long)x);
s.erase(s.find(-((sum[1][i]+sum[2][n-1]-sum[2][i]+arr[2][i]+p+p)%p)));
ans=max(ans,x);
}
printf("%d",ans);
return 0;
}
这是算法马拉松一道题。当时想法方向是正确的可惜没有想到STL。
题意3*n的矩阵。。要走出一条取余最大路。。
看到3肯定是在这里做文章。。那么可以枚举第一行二分剩下的嘛。。
到这里思路都很清晰,但是考虑到如果不删除(删除当前节点不合法的走法,移动一下删一个)的话,二分就结果不一定正确了。。这就十分尴尬
赛后看题解可以 multiset来删除,当然也可以map了。。。这里就是经验的问题了
二分时候要注意一些地方,一个最优答案当然是靠近P-1了,那么枚举的x怎么靠近P-1呢,当然有两种方法,一是x+y靠近p-1,要么是x+y靠近2*p-1了。
然后在multiset里面二分即可。。
这里要学习stl的应用,自己根本没有领会到stl的精髓啊。。。蒟蒻加油!
#include <iostream>
#include <set>
#include <stdio.h>
#include <algorithm>
#include <fstream>
using namespace std;
const int maxn=100005;
long long n,p;
long long arr[3][maxn];
long long sum[3][maxn];
multiset<int> s;
int main()
{
scanf("%d%d",&n,&p);
for(int i=0;i<3;i++){
for(int j=0;j<n;j++){
scanf("%d",&arr[i][j]);
arr[i][j]=arr[i][j]%p;
}
}
sum[0][0]=arr[0][0]%p;
sum[0][1]=arr[0][1]%p;
sum[0][2]=arr[0][2]%p;
for(int i=0;i<3;i++){
for(int j=1;j<n;j++){
sum[i][j]=(sum[i][j-1]+arr[i][j])%p;
}
}
for(int j=0;j<n;j++){
s.insert(-((sum[1][j]+sum[2][n-1]-sum[2][j]+arr[2][j]+p+p)%p));
}
int ans=0;
int x;
multiset<int>::iterator it;
for(int i=0;i<n;i++){
it=s.lower_bound(-(p-1-(sum[0][i]-sum[1][i]+arr[1][i]+p+p)%p));
if(it!=s.end())
x=(sum[0][i]-sum[1][i]+arr[1][i]-*it+p+p)%p;
it=s.lower_bound(-(p+p-1-(sum[0][i]-sum[1][i]+arr[1][i]+p+p)%p));
if(it!=s.end())
x=max((sum[0][i]-sum[1][i]+arr[1][i]-*it+p+p)%p,(long long)x);
s.erase(s.find(-((sum[1][i]+sum[2][n-1]-sum[2][i]+arr[2][i]+p+p)%p)));
ans=max(ans,x);
}
printf("%d",ans);
return 0;
}
相关文章推荐
- goto 语句和标号
- Intellij 打可执行jar包
- 网站桌面端和手机端不同url的设置
- SSE指令集学习:Compiler Intrinsic
- 2016最新4套旅游网站建站程序系统优缺点分析
- Eclipse 安装EGit失败
- Thrift 原理与使用实例
- 在Eclipse中配置Maven
- stm32 io模拟spi通信
- tornado系列:用cookie进行用户验证
- C++ 子类继承带参的父类构造函数应该怎么写
- java集合08--List总结
- SpringBoot集成Swagger
- 从头认识多线程-2.12 synchronized ()代码块不单可以用this,也可以用其他对象
- 学习进度条09
- 适配ios9出现的问题:-canOpenURL: failed for URL
- Android进阶之Fragment和Activity之间通过setArguments传递复杂参数
- 最全面的AndroidStudio配置指南总结-包括护眼模式
- 开始记录学习产品的心得
- <<UML for Java Programmers>> 第11章读书笔记