题目地址
题意:除了最高领导s以外每个人都有一个顶头上司,每个人说出他有num[i]个上司,问最少有多少个人说谎了。
思路:因为每个人都有一个顶头上司,所以一定是连续的,并且除了最高领导外任何人都不可能是0,所以这个人不是最高领导,但是他又没有上司,所以一定是说谎了的,把他的上司数至为最大的,所以前面有不是连续的就先利用这些人,已达到最小(一定要判断最高领导的上司数是不是0,如果不是就说明说谎了)。
#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <cstdio>
#include <algorithm>
#define LL long long
#define N 200010
#define M 50010
#define inf 0x3f3f3f3f
using namespace std;
const LL mod = 1e9 + 7;
const double eps = 1e-9;
int num[N], flag[N];
int main() {
cin.sync_with_stdio(false);
int n, s;
int ans, cnt;
while (cin >> n >> s) {
ans = 0;
memset(flag, 0, sizeof(flag));
for (int i = 1; i <= n; i++) {
cin >> num[i];
if (i != s&&num[i] == 0) {
ans++;
num[i] = inf;
}
}
if (num[s] != 0) {
ans++;
num[s] = 0;
}
flag[0] = 1;
cnt = 1;
sort(num + 1, num + 1 + n);
for (int i = 1; i <= n; i++) {
if (num[i] == 0 || num[i] == inf) {
continue;
}
if (!flag[num[i] - 1]) {
if (num[n] != inf) {
ans++;
}
flag[cnt] = 1; cnt++;
if (n != i) {
i--;
}
n--;
continue;
}
flag[num[i]] = 1;
cnt = num[i] + 1;
}
cout << ans << endl;
}
return 0;
}