A. UCloud 机房的网络搭建
注意0,1的时候特判一下即可。
#include <bits/stdc++.h>
using namespace std;
int a[108];
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n, m;
cin >> n >> m;
int sum = 0;
for(int i = 0; i < m; ++i) {
cin >> a[i];
sum += a[i];
}
if(n <= 1) {
cout << 0 << endl;
return 0;
}
sort(a, a+m);
if(sum - m + 1 < n) {
cout << "Impossible" << endl;
return 0;
}
int cnt = 0, cc = 0;
for(int i = m-1; i >= 0 && a[i] != 0; --i) {
cc++;
cnt += a[i];
if(cnt - cc + 1 >= n) break;
}
cout << cc << endl;
return 0;
}
C. UCloud 的安全秘钥(简单)+(中等)
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 50000 + 7;
int s[MAXN], t[MAXN];
int num1[MAXN], num2[MAXN];
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n, m;
cin >> n;
for(int i = 0; i < n; ++i) {
cin >> s[i];
}
cin >> m;
int k;
while(m--) {
int ans = 0;
cin >> k;
if(k > n) {
cout << 0 << endl;
continue;
}
fill(num1, num1 + MAXN, 0);
fill(num2, num2 + MAXN, 0);
for(int i = 0; i < k; ++i) {
cin >> t[i];
num2[t[i]]++;
num1[s[i]]++;
}
int cnt = 0;
for(int i = 1; i <= n; ++i) {
if(num1[i] != num2[i]) {
cnt++;
}
}
if(cnt == 0) {
ans++;
}
for(int i = k; i < n; ++i) {
int pre = i - k;
int cur = i;
if(num1[s[pre]] == num2[s[pre]]) cnt++;
else if(num1[s[pre]] - 1 == num2[s[pre]]) cnt--;
num1[s[pre]]--;
if(num1[s[cur]] == num2[s[cur]]) cnt++;
else if(num1[s[cur]] + 1 == num2[s[cur]]) cnt--;
num1[s[cur]]++;
if(cnt == 0) ans++;
}
cout << ans << endl;
}
return 0;
}
C. UCloud 的安全秘钥(困难)
关了流的cin都会卡,以后还是老老实实用scanf把!,这里总长度不会超过200000, 所以有很多很小的匹配串,把长度在10以内的预处理一下。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100000 + 7;
int n, k;
int s[MAXN], t[MAXN];
int num1[MAXN], num2[MAXN];
map<vector<int>, int > ans;
void check() {
vector<int> v;
for(int i = 0; i < k; ++i) {
v.push_back(t[i]);
}
sort(v.begin(), v.end());
printf("%d\n", ans[v]);
}
int main() {
scanf("%d", &n);
for(int i = 0; i < n; ++i) {
scanf("%d", &s[i]);
}
for(int i = 0; i < n; ++i) {
vector<int> v;
for(int j = i; j < i + 10 && j < n; ++j) {
v.push_back(s[j]);
sort(v.begin(), v.end());
ans[v]++;
}
}
int m;
scanf("%d", &m);
while(m--) {
int ans = 0;
scanf("%d", &k);
for(int i = 0; i < k; ++i) {
scanf("%d", &t[i]);
}
if(k > n) {
puts("0");
continue;
}
if(k <= 10) {
check();
continue;
}
memset(num1, 0, sizeof(num1));
memset(num2, 0, sizeof(num2));
for(int i = 0; i < k; ++i) {
num1[s[i]]++;
num2[t[i]]++;
}
int cnt = 0;
for(int i = 1; i <= n; ++i) {
if(num1[i] != num2[i]) {
cnt++;
}
}
if(cnt == 0) {
ans++;
}
for(int i = k; i < n; ++i) {
int pre = i - k;
int cur = i;
if(num1[s[pre]] == num2[s[pre]]) cnt++;
else if(num1[s[pre]] - 1 == num2[s[pre]]) cnt--;
num1[s[pre]]--;
if(num1[s[cur]] == num2[s[cur]]) cnt++;
else if(num1[s[cur]] + 1 == num2[s[cur]]) cnt--;
num1[s[cur]]++;
if(cnt == 0) ans++;
}
printf("%d\n", ans);
}
return 0;
}