Codeforces 729E Subordinates

题目链接:http://codeforces.com/problemset/problem/729/E


 

既然每一个人都有一个顶头上司,考虑一个问题:

  如果这些人中具有上司数目最多的人有$x$个上司,那么一定存在一些人,他们分别有$x-1,x-2...1$个上司。

首先如果$s$位置上的上司数目不为$0$,非$s$位置上的上司数目为$0$它们就是一定说错了话的。

问题转化为了:将合法的上司数目从小到大小排序,我们现在要这个序列的数字连续单调不降,并且相差不能为大于$1$。

有一人些已经说错了话,考虑用他们补足中间的差值的空隙,如果补不足再贪心的把最大的减小往前补。

 

注意如果最后一个人和前一个人差值有间隙,直接把它他减小即可。


 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<cstring>
 8 using namespace std;
 9 #define maxn 1001000
10 #define llg int
11 #define inf 0x7fffffff
12 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
13 llg n,m,la,a[maxn],ans,s;
14 bool bj[maxn];
15 int main()
16 {
17     yyj("Subordinates");
18     cin>>n>>s;
19     for (llg i=1;i<=n;i++)
20     {
21         scanf("%d",&a[i]);
22         if (i==s)
23         {
24             if (a[i]!=0) ans++;
25             a[i]=0;
26         }
27         if (a[i]==0 && i!=s) a[i]=inf,ans++;
28     }
29     sort(a+1,a+n+1);
30     bj[0]=1; la=1;
31     for (llg i=1;i<=n;i++)
32     {
33         if (a[i]==0 || a[i]==inf) continue;
34         if (!bj[a[i]-1])
35         {
36             if (a[n]!=inf) ans++;
37             bj[la]=1; la=la+1;
38             if (n!=i) i--;
39             n--;
40             continue;
41         }
42         bj[a[i]]=1; la=a[i]+1;
43     }
44     cout<<ans;
45     return 0;
46 }

 

posted @ 2017-03-13 21:28  №〓→龙光←  阅读(207)  评论(0编辑  收藏  举报