Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) ..C. Jury Marks

版权声明:QQ764229539,欢迎指正! https://blog.csdn.net/Haipai1998/article/details/75099882

依旧是STL,用到了map,vector,unique。

题意:一个人有一个额最初的成绩,告诉你N个评委的分数(顺序),每次评委打完分,都是最初的成绩加上前缀和,告诉你k个所听到的成绩(随意的顺序),问最初的分数可能是多少。
思路:先预处理出前缀和,穷举每个分数对应的可能最初分数(k[i]-前缀和),对应记录该分数的出现次数,如果==k(满足k个数都出现的情况)就符合条件,cnt++。 对于这道题必须得用map做,因为前缀和可能是负数,如果你开个数组来hash,那么要加上4e6,那么这就很危险把。因为可能会到8e6就炸了。 所以用map来存储每个 数字 对应的key,然后再查一遍 就可以了。
注意,如果有前缀和相同的要剔除,否则一个ki对应同一个初始分数就会出现多次累加,最后答案就会比真实答案要大的。
AC代码的后面,附上我很诡异的TLE code

/*If I get TLE , it is good.If I get AC,it's NICE !*/
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int MAXN=1e7+10;
const ll mod=1e9+7;
using namespace std;
typedef long long ll;
vector <int> temp;
map <int,int > mp;
int sum[3000];
int main(void)
{
    int n,k;
    cin >> n>> k;
    memset(sum,0,sizeof(sum));
    for(int i=1;i<=n;i++)
    {
        int t;
        scanf("%d",&t);
        sum[i]=t+sum[i-1];
    }
    //for(int i=1;i<=n;i++)
    //    printf("%d\n",sum[i]);
    sort(sum+1,sum+1+n);
    int len=unique(sum+1,sum+1+n)-(sum+1);
    //for(int i=1;i<=len;i++)
    //    printf("%d\n",sum[i]);
    mp.clear();
    //int mmax=-INF;
    //int mmin=INF;
    for(int i=1;i<=k;i++)
    {
        int t;
        scanf("%d",&t);
        for(int j=1;j<=len;j++)
        {
           temp.push_back(t-sum[j]);
        }
    }
    sort(temp.begin(),temp.end()); // 加上sort AC,不加TLE,比下面的TLE代码在更早的测试数据就T了,所以我怀疑map的插入效率可能和原来vector的单调性有关系。越单调,速度越快。
    int cnt=0;
    //int index=mmax;
    for(int i=0;i<temp.size();i++)
    {
        mp[temp[i]]++;
    }
    for(int i=0;i<temp.size();i++)
    {
       if( mp[temp[i]] ==k )
            mp[temp[i]]=0,cnt++;
    }
    printf("%d\n",cnt);
}

// 这个TLE的原因我猜可能是因为每次都要max,min

TLE代码
/*If I get TLE , it is good.If I get AC,it's NICE !*/
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int MAXN=1e7+10;
const ll mod=1e9+7;
using namespace std;
typedef long long ll;
vector <int> temp;
map <int,int > mp;
int sum[3000];
int main(void)
{
    int n,k;
    cin >> n>> k;
    memset(sum,0,sizeof(sum));
    for(int i=1;i<=n;i++)
    {
        int t;
        scanf("%d",&t);
        sum[i]=t+sum[i-1];
    }
    //for(int i=1;i<=n;i++)
    //    printf("%d\n",sum[i]);
    sort(sum+1,sum+1+n);
    int len=unique(sum+1,sum+1+n)-(sum+1);
    //for(int i=1;i<=len;i++)
    //    printf("%d\n",sum[i]);
    mp.clear();
    int mmax=-INF;
    int mmin=INF;
    for(int i=1;i<=k;i++)
    {
        int t;
        scanf("%d",&t);
        for(int i=1;i<=len;i++)
        {
            mp[t-sum[i]]++;
            mmax=max(mmax,t-sum[i]);
            mmin=min(mmin,t-sum[i]);
        }
    }
    int cnt=0;
    int index=mmax;
    for(int i=mmin;i<=index;i++)
    {
        //printf("%d:%d\n",i,mp[i]);
        if(mp[i]==k)
            cnt++;
    }
    printf("%d\n",cnt);
}

最后对STL中unique这个封装函数解释一下,这个函数返回没重复的序列的最后地址,其并没有把重复的数字删除,而是放到最后地址的后面了。
会写unique , 也是这题的一大关键。

做完这道题的心得:
1.学习了 STL 中 unique的用法,原理
2.对map插入数据的时候,先用vector存储,然后再sort,可以大大节省时间。
3.STL真的很重要

阅读更多
换一批

没有更多推荐了,返回首页