A
link
很简单 配列を順にアクセスし、\(k\)で割った余りが\(0\)かどうか判定する。余りが\(0\)の場合、\(a_i/k\)を出力する。
クリックしてコードを表示``` #include<bits/stdc++.h>
using namespace std;
int n, k; int data[105];
int main() { cin >> n >> k;
for(int i = 1; i <= n; ++i) {
cin >> data[i];
if(data[i] % k == 0) {
cout << data[i] / k << " ";
}
}
return 0;
}
B
=
link
前置知識:\\(unordered\\_map\\)(または\\(map\\))
\\(unordered\\_map\\)は連想配列であり、キーに任意の型(文字列など)を使用できる。
、与えられた文字列的所有異なる部分文字列を数える問題。
部分文字列を列挙し、以前に出現したことがあるかどうかを確認する。
列挙方法:
外側の2重ループで部分文字列の開始位置と終了位置を指定し、内側のループで指定範囲内の文字を結合して部分文字列を作成する。
確認方法:
\\(unordered\\_map\\)を使用して、その文字列が既に存在するかを調べる。存在しない場合は答えをインクリメントし、マップに登録する。
クリックしてコードを表示```
#include<bits/stdc++.h>
using namespace std;
char text[105];
int length;
string substr;
unordered_map<string, int> seen;
int answer;
int main() {
cin >> text + 1;
length = strlen(text + 1);
for(int i = 1; i <= length; ++i) {
for(int j = i; j <= length; ++j) {
substr.clear();
for(int p = i; p <= j; ++p) {
substr += text[p];
}
if(!seen[substr]) {
seen[substr] = 1;
answer++;
}
}
}
cout << answer;
return 0;
}
C
link
まず、各要素を第1週の勤務日企业与第2週の休日にマッピングする。 その後、、第1週の勤務日から第2週の休日に移動できる要素を見つけ、移动过程中第2週の休日の範囲外に出てはいけない。 移动可能な要素の中で最大値と最小値を求める。移動後の最大値が休日の時間を超える場合、范围外に移動してしまうため不可。 別の方法として、从前面截取一段放到后面的方式来検討する。
クリックしてコードを表示``` #include<bits/stdc++.h>
#define int long long
using namespace std;
int n, work, rest; int timeData[200005]; int current, result = 1e18; int maximumVal, minimumVal = 1e18;
int main() { cin >> n >> work >> rest; for(int i = 1; i <= n; ++i) { cin >> current; current %= (work + rest); if(current == 0) current = work + rest; if(current <= work) { current += work + rest; } maximumVal = max(maximumVal, current); minimumVal = min(minimumVal, current); timeData[i] = current; }
sort(timeData + 1, timeData + 1 + n);
for(int i = 1; i < n; ++i) {
result = min(result, work + rest - timeData[i+1] + timeData[i] + 1);
}
result = min(result, maximumVal - minimumVal + 1);
if(result <= work) cout << "Yes";
else cout << "No";
return 0;
}
D
=
link
まず、\\(c\\)のビット表現における1の个数を\\(cnt\\)とする。
場合分け:
- \\(cnt > a+b\\)の場合:不可
- \\(cnt = a+b\\)の場合:\\(a\\)個の1を最初の数に、\\(b\\)個の1を2番目の数に割り当てで対応するビット位置を决定する
- \\(cnt < a+b\\)の場合:残り(\\(a+b-cnt\\))が奇数なら不可、偶数なら可能
偶数の場合:首先、\\(a\\)と\\(b\\)から余分を平等のように去除し、その후残りの\\(a\\)個の1を最初の数に、\\(b\\)個の1を2番目の数に割り当てる。次に、\\(c\\)のビットが0の位置から足够的数を 찾아서両方の数を1にする。
注意:結果は\\(2^{60}\\)を超えない
クリックしてコードを表示```
#include<bits/stdc++.h>
#define int long long
using namespace std;
int A, B, C, bitCount;
int cbits[65];
int resultA[65], resultB[65];
int main() {
cin >> A >> B >> C;
int temp = C;
for(int i = 0; i <= 59; ++i) {
if(temp & 1) {
cbits[i] = 1;
bitCount++;
}
temp >>= 1;
}
if(bitCount > A + B || (A + B - bitCount) % 2 != 0) {
cout << -1;
return 0;
}
int extra = (A + B - bitCount) / 2;
A -= extra;
B -= extra;
for(int i = 0; i <= 59; ++i) {
if(cbits[i]) {
if(A > 0) {
resultA[i] = 1;
A--;
} else if(B > 0) {
resultB[i] = 1;
B--;
}
}
}
if(A < 0 || B < 0) {
cout << -1;
return 0;
}
for(int i = 0; i <= 59; ++i) {
if(!cbits[i]) {
if(extra > 0) {
resultA[i] = 1;
resultB[i] = 1;
extra--;
}
}
}
if(extra > 0) {
cout << -1;
return 0;
}
int num1 = 0, num2 = 0;
int weight = 1;
for(int i = 0; i <= 59; ++i) {
if(resultA[i]) num1 += weight;
if(resultB[i]) num2 += weight;
weight *= 2;
}
cout << num1 << " " << num2 << endl;
return 0;
}