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

猜你喜欢

转载自www.cnblogs.com/lcxer/p/10642708.html