题目大意:

输入n,m,分别表示人的个数和颜色的个数,下一行输入n个数,对应每个人的颜色,最后一行输入对应每个颜色的人应有的数量;

问是否能找出一个区间,满足条件但有多余的人,输出多余的人最少的个数,如果连条件都不能满足,输出-1

基本思路:

尺取法,自己写的没有设置l,r标记,也没有用set,一直卡在样例2,之后又卡37,不知道哪里错了,找了很久,后来干脆学习别人的思路吧。

设一个l指针指向当前数列左边,从左往右扫描一遍,将当前颜色记录,

当所有颜色都得到后,进行判断,如果当前l指向的颜色大于需要的颜色,l后移一位,然后更新答案

果然尺取还是应该定义l,r标记的,这样比较好些,也比较好思考;

代码如下:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<set> using namespace std; typedef long long ll;
typedef long long LL;
typedef pair<int,int> pii;
const int inf = 0x3f3f3f3f;
const int maxn = 200000+10;
const ll mod = 1e9+9;
set<int>q;
int col[maxn],cnt[maxn],k[maxn];
int main(){
int n,m,sum=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&col[i]);
}
for(int i=1;i<=m;i++){
scanf("%d",&k[i]);
if(k[i]){
q.insert(i);
}
sum+=k[i];
}
int l=1,ans=inf;
for(int r=1;r<=n;r++){
int c=col[r];
++cnt[c];
if(cnt[c]==k[c]){
q.erase(c);
}
if(q.empty()){
while(l<=r&&cnt[col[l]]>k[col[l]]){
--cnt[col[l]];
l++;
}
ans=min(ans,r-l+1-sum);
}
}
if(ans==inf){
ans=-1;
}
printf("%d\n",ans);
return 0;
}

  

最新文章

  1. 我离baidu.com有几跳
  2. js加密解密
  3. sql:select赋值和set赋值的区别
  4. office 软件常用备忘(删除线/冻结等)
  5. python代码
  6. VB程序逆向反汇编常见的函数
  7. namenode无法自动切换的问题
  8. [状压dp]HDU3001 Travelling
  9. 一个很简单的SqlServer生成常用C#语句工具的诞生
  10. solr可用于集群的搜索 【转】
  11. sql 查找数据库中某字符串所在的表及字段
  12. Python3基础 用 while循环实现 斐波那契数列
  13. HDU1548:A strange lift(Dijkstra或BFS)
  14. LINUX 笔记-文件隐藏属性
  15. (一二三)基于GCD的dispatch_once实现单例设计
  16. Linux 文件系统结构、磁盘的管理
  17. Codeforces Round #317 (div 2)
  18. paymob QB冲值接口
  19. Summary: Java中函数参数的传递
  20. 解决 Ubuntu 14.04 图形界面无法正常显示 问题

热门文章

  1. CF286E Ladies&#39; Shop FFT
  2. [CF959A]Mahmoud and Ehab and the even-odd game题解
  3. python 文件读写操作打开模式
  4. Cookie由谁设置、怎么设置、有什么内容?
  5. 622FThe Sum of the k-th Powers
  6. jmeter之cookies登录
  7. PHP继承及实现
  8. MySQL 安装示例数据库(employee、world、sakila、menagerie 等)
  9. 洛谷T89643 escape
  10. LeetCode 144. Binary Tree Preorder Traversal 动态演示