コンテスト情報
データ:2019年6月30日には
解決:4/7
ソリューション
A.ステッカーやおもちゃ
質問の意味:
あり(\)\アイテム\(S \) A、\(B \)のアイテム\(のt \)数ヶ月、これらのアイテムは、今にロードされます\(N \)箱、各ボックスはわずかに約あります3例:
- 唯一の\(\)の項目
- のみ\(B \)項目
- \(\)の記事や\(B \)項目
今あなたが、少なくとも持って保証することができますが、少なくとも撮りたいどのように多くのボックス、頼む\(\)のアイテムと\(B \)項目を。
アイデア:
鳩の巣原理は、することが明らかである(A \)\少なくとも取って、アーティクル- (S + 1 \ N \ ) ボックスを持つことができます\(A \)項目を。
同様に、のための\(B \)物品は、少なくとも取る( - T + 1 \ n \ ) ボックス。
答えは\(ミン(N - S +1 、N - T + 1)\)
コード:
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, s, t;
int T; scanf("%d", &T);
while (T--) {
scanf("%d%d%d", &n, &s, &t);
int res = max(n - s + 1, n - t + 1);
printf("%d\n", res);
}
return 0;
}
B.レターショップ
問題の意味:
文字列がある\(sが\) 、常に文字列尋ねる\(のt \)を、最小尋ねる\を(S \)プレフィックス文字は、このプレフィックスは、文字列で構成している可能性があります\(トンを\) 。
思考:
2、その後、プレフィックスと文字の数を維持することができます。
コードワン:
#include <bits/stdc++.h>
using namespace std;
#define N 200010
int n, m, lens, lent;
char s[N], t[N];
int sum[N][27];
int cnt[27];
bool ok(int x) {
for (int i = 0; i < 26; ++i) {
if (sum[x][i] < cnt[i]) {
return 0;
}
}
return 1;
}
int main() {
while (scanf("%d", &n) != EOF) {
memset(sum, 0, sizeof sum);
scanf("%s", s + 1); lens = strlen(s + 1);
for (int i = 1; i <= lens; ++i) {
++sum[i][s[i] - 'a'];
for (int j = 0; j < 26; ++j) {
sum[i][j] += sum[i - 1][j];
}
}
scanf("%d", &m);
while (m--) {
scanf("%s", t + 1); lent = strlen(t + 1);
memset(cnt, 0, sizeof cnt);
for (int i = 1; i <= lent; ++i) {
++cnt[t[i] - 'a'];
}
int l = 1, r = n, res = -1;
while (r - l >= 0) {
int mid = (l + r) >> 1;
if (ok(mid)) {
r = mid - 1;
res = mid;
} else {
l = mid + 1;
}
}
printf("%d\n", res);
}
}
return 0;
}
II考える:
メンテナンス\(S \)の文字の文字列クラス\を(私は\)番目の位置、には明らかであろう(T \)を\文字の種類ごとに文字列を持っている\(X \) 、番目の単語を\(S \)の長さより大きいか、文字の接頭文字列に等しい\()X \位置。
コードII:
#include <bits/stdc++.h>
using namespace std;
#define N 200010
int n, m, lens, lent;
char s[N], t[N];
int sum[N][27];
int cnt[27];
bool ok(int x) {
for (int i = 0; i < 26; ++i) {
if (sum[x][i] < cnt[i]) {
return 0;
}
}
return 1;
}
int main() {
while (scanf("%d", &n) != EOF) {
memset(sum, 0, sizeof sum);
scanf("%s", s + 1); lens = strlen(s + 1);
for (int i = 1; i <= lens; ++i) {
++sum[i][s[i] - 'a'];
for (int j = 0; j < 26; ++j) {
sum[i][j] += sum[i - 1][j];
}
}
scanf("%d", &m);
while (m--) {
scanf("%s", t + 1); lent = strlen(t + 1);
memset(cnt, 0, sizeof cnt);
for (int i = 1; i <= lent; ++i) {
++cnt[t[i] - 'a'];
}
int l = 1, r = n, res = -1;
while (r - l >= 0) {
int mid = (l + r) >> 1;
if (ok(mid)) {
r = mid - 1;
res = mid;
} else {
l = mid + 1;
}
}
printf("%d\n", res);
}
}
return 0;
}
C. Vasyaと配列
質問の意味: