洛谷P1638 逛画展

题目大意:

    画展中有n排好序幅画,分别由m位画家所画,看一幅画一元,问从第几幅看到第几幅既能看遍所有画家的至少一幅作品,还能省钱。(N<=1000000 , M<=2000)

思路:

    按钱数二分。check时,用一个数组记录可以看到的每个画家的作品数,在记录一个所看到画家数,移动长度为钱数的区间,查看加进来的和出去的并更新作品数和画家数,当画家数为m就合理。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 
 6 using namespace std;
 7 
 8 int n,m,a[1000006],ansr,ansl,have[2002];
 9 
10 bool check(int paint)
11 {
12     memset(have,0,sizeof(have));
13     int youxiao=0;
14     int i=1,j=paint;
15     for(int k=1;k<=paint;k++)
16     {
17         have[a[k]]++;
18         if(have[a[k]]==1)youxiao++;
19     }
20     while(j<=n)
21     {
22         if(youxiao==m)
23         {
24             ansl=i;
25             ansr=j;
26             return true;
27         }
28         have[a[i]]--;
29         if(!have[a[i]])youxiao--;
30         i++;
31         j++;
32         have[a[j]]++;
33         if(j<=n&&have[a[j]]==1)youxiao++;
34     }
35     return false;
36 }
37 
38 int main()
39 {
40     scanf("%d%d",&n,&m);
41     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
42     int l,r;
43     l=1;r=n;
44     while(l<r)
45     {
46         int mid=(l+r)/2;
47         if(check(mid))
48         {
49             r=mid;
50         }
51         else
52         {
53             l=mid+1;
54         }
55     }
56     if(check(r));
57     printf("%d %d\n",ansl,ansr);
58     return 0;
59 } 
View Code

 

    

posted @ 2018-10-09 09:33  liqgnonqfu  阅读(201)  评论(0编辑  收藏  举报