CF Round #547 (Div. 3) F1(Easy) and F2(Hard) - Same Sum Blocks

题目链接:

F1:http://codeforces.com/contest/1141/problem/F1
F2:http://codeforces.com/contest/1141/problem/F2

题意:

给你一个长度为n的整数序列,让你求最大数目的不相交区间且和这些区间和相等,区间长度不一定相同,输出区间个数,及每个区间的左右端点位置(非下标);

分析:

先写个大致思路,就是根据某一个和来分类,分到一类的区间不能相交,看哪一类的个数最多,大概就是一个区间贪心问题;

#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<set>
#include<map>
using namespace std;

const int inf=0x7f7f7f7f;
const int maxn=1e1+50;
const int N=1e4+50;
typedef long long ll;
typedef struct{
    ll u,v,next,w;
}Edge;
Edge e[N];

int cnt,head[N];

inline void add(int u,int v){
    e[cnt].u=u;
    e[cnt].v=v;
    //e[cnt].w=w;
    // e[cnt].f=f;
    e[cnt].next=head[u];
    head[u]=cnt++;
    // e[cnt].u=v;
    // e[cnt].v=u;
    // e[cnt].w=0;
    // e[cnt].f=-f;
    // e[cnt].next=head[v];
    // head[v]=cnt++;
}
inline void write(int x)
{
     if(x<0) 
        putchar('-'),x=-x;
     if(x>9)
        write(x/10);
     putchar(x%10+'0');
}
inline int read()
{
    int x = 0;
    int f = 1;
    char c = getchar();
    while (c<'0' || c>'9'){    
        if (c == '-')
            f = -1;
        c = getchar();
    }
    while (c >= '0'&&c <= '9'){
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x*f;
}

int n,a[N],sum[N];
map<int ,vector<pair<int ,int > > >mp;
vector<pair<int ,int > >num;
int main() {
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        sum[i]=sum[i-1]+a[i];
    }
    map<int,int >mp1;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++){
            int t=sum[i]-sum[j-1];
            //cout<<t<<endl;
            //mp1[t]表示到目前为止获得区间和为t的最右边区间的右端点位置
            if(mp1[t]<j){
                //cout<<i<<" "<<j<<endl;
                mp[t].push_back({j,i});
                mp1[t]=i;
            }
        }
    }
    int maxsize=0;
    map<int ,vector<pair<int ,int > > >::iterator it=mp.begin();
    for(;it!=mp.end();it++){
        if((*it).second.size()>maxsize){
            maxsize=(*it).second.size();
            num=(*it).second;
        }
    }
    cout<<maxsize<<endl;
    for(int i=0;i<maxsize;i++){
        int f=num[i].first,s=num[i].second;
        cout<<f<<" "<<s<<endl;
    }
    return 0;
}

(仅供个人理解)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值