Atcode - ABC 210 - C - Colorful Candies

Atcoder Beginner Contest 210

C - Colorful Candies:

题目:

C - Colorful Candies

Time Limit: 2 sec / Memory Limit: 1024 MB
Score : 300points

Problem Statement

There are N candies arranged in a row from left to right.

Each of these candies has one color that is one of the 10^9 colors called Color 1, Color 2, ……, and Color 10^9.
For each i=1,2,…,N the color of the i-th candy from the left is Color ci.
From this row, Takahashi can choose K consecutive candies and get them.

That is, he can choose an integer i such that 1 ≤ i ≤ N−K+1 and get the i-th, (i+1)-th, (i+2)-th, ……, (i+K−1)-th candy from the left. Takahashi likes to eat colorful candies, so the more variety of colors his candies have, the happier he will be.

Print the maximum possible number of distinct colors in candies he gets. Constraints 1 ≤ K ≤ N ≤3×10^5 , 1≤ ci ≤10^9
All values in input are integers.


输入输出:

lnput
Input is given from Standard Input in the following format:

N K
c1 c2 c3 … cN

Output
Print the maximum possible number of distinct colors in candies Takahashi gets.

Simple input 1:

10 6
304621362 506696497 304621362 506696497 834022578 304621362 414720753 304621362 304621362 414720753

output:4

Simpe input 2:

5 5
4 4 4 4 4

output :1


C++ 代码:

思路:

注意到本题糖果数量N只有3 *10^5 个,但是用来表示糖果颜色ci的数据范围却是10^9,所以如果开一个10的9次方的数组来存取糖果的颜色是显然不合理的,对于这种情况,我是采用离散化的方式来实现用大小为3 * 10^5的数组来存取ci。

此外,为了防止超时的问题,我们不能直接来一个三重循环调用,要将问题分解,可以发现对于N个ci, 我们可以每次取出K个数据来分析,循环遍历,而下一组K个数据比较前一组的差别只在于ci 和 c(i-k), 发现这个规律,我们可以只遍历一遍数组就能得到答案。

具体过程看代码:

#include<iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> alls;

// 二分求出x对应的离散化的值
int find(int x) // 找到第一个大于等于x的位置
{
    int l = 0, r = alls.size() - 1;
    while (l < r)
    {
        int mid = l + r >> 1;
        if (alls[mid] >= x) r = mid;
        else l = mid + 1;
    }
    return r+1 ; // 映射到 1, 2, ...n
}

int a[300010];
int b[300010]={0};

int main(){
	int n,k,x;
	cin >> n >> k;
	for(int i=1;i<=n;i++){
		cin >> x;
		a[i]=x;
		alls.push_back(x);
	}
	sort(alls.begin(), alls.end());
	alls.erase(unique(alls.begin(), alls.end()), alls.end());
	int cnt=0;
	int max=0;
	for(int i=1; i<=k; i++){
		if(b[find(a[i])] == 0) cnt++;
		b[find(a[i])]++;
	}
	max = cnt;
	for(int i=k+1; i<=n; i++){
		b[find(a[i-k])]--;
		if(b[find(a[i-k])] == 0) cnt--;
		if(b[find(a[i])] == 0) cnt++;
		b[find(a[i])]++;
		if(cnt > max) max = cnt;
		if(max == k){
		 cout << k;
		 return 0;
		}
	}
	cout << max;
	return 0;
}

AND
附上官方的题解
采用map的方法来解决,更简单明了

#include <iostream>
#include <map>

using namespace std;

int n, k;
int c[300005];
map<int, int> mp;

int main(void)
{
  cin >> n >> k;
  for(int i = 1; i <= n; i++) cin >> c[i];

  for(int i = 1; i <= k; i++) mp[c[i]]++;
  int ans = mp.size();

  for(int i = k+1; i <= n; i++){
    mp[c[i]]++;
    mp[c[i-k]]--;
    if(mp[c[i-k]] == 0) mp.erase(c[i-k]);
    ans = max(ans, (int)mp.size());
  }
  cout << ans << endl;

  return 0;
}

map 的基本操作函数:
C++ Maps 是一种关联式容器,包含“关键字/值”对:
基本操作:

begin() ———— 返回指向 map 头部的迭代器
erase() ————删除一个元素
max_size() ———— 返回可以容纳的最大元素个数
find() ———— 查找一个元素

map提供的是一种键值对容器,里面的数据都是成对出现,在解题的时候非常好用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值