您的位置:首页 > 其它

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

2017-07-14 11:07 507 查看
依旧是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真的很重要
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces
相关文章推荐