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]);
}