CF1141F Same Sum Blocks(easy/hard)

传送门easy

传送门hard

切水题的感觉真好

看到数据范围这么小,所以暴力枚举所有的可能,然后用map+vector存下每种值的区间,然后贪心去选

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
void read(int &x) {
	char ch; bool ok;
	for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
	for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
}
#define rg register
const int maxn=1.5e3+10;
map<int,vector<pair<int,int> > >mp; 
int n,a[maxn],s[maxn],w[maxn*maxn],tot,ans,l[maxn],r[maxn],ll[maxn],rr[maxn];
bool solve(int k)
{
	int sum=0,las=0;sort(mp[k].begin(),mp[k].end());int now=mp[k].size();
	for(rg int i=0;i<now;i++)if(las<mp[k][i].second)las=mp[k][i].first,ll[++sum]=mp[k][i].second,rr[sum]=las;
	if(sum>ans)memcpy(l,ll,sizeof l),memcpy(r,rr,sizeof r),ans=sum;
	return 0;
}
int main()
{
	read(n);
	for(rg int i=1;i<=n;i++)read(a[i]),s[i]=s[i-1]+a[i];
	for(rg int i=1;i<=n;i++)
		for(rg int j=i;j<=n;j++)
			w[++tot]=s[j]-s[i-1],mp[w[tot]].push_back(make_pair(j,i));
	sort(w+1,w+tot+1);tot=unique(w+1,w+tot+1)-w-1;
	for(rg int i=1;i<=tot;i++)if(solve(w[i]))break;
	printf("%d\n",ans);
	for(rg int i=1;i<=ans;i++)printf("%d %d\n",l[i],r[i]);
}
posted @ 2019-04-02 15:03  蒟蒻--lichenxi  阅读(253)  评论(0编辑  收藏  举报