A. 长码竞赛
不难发现,日期 52020330 中有三个 0,两个 2,两个 3 和一个 5。所以一个一个数字遍历,直到这四种数字数量足够即可。
#include <bits/stdc++.h>
using namespace std;
main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<int> cnt(10);
cnt[0] = 3, cnt[2] = 2, cnt[3] = 2, cnt[5] = 1;
auto check = [&]() {
for (auto x : cnt)
if (x > 0)
return false;
return true;
};
int ans = -1;
for (int i = 1, x; i <= n; i++) {
cin >> x;
--cnt[x];
if (ans == -1 && check())
ans = i;
}
cout << ans << '\n';
}
}
B. 浮点表示
直接模拟当然是可以的,但其实注意到绝大多数现代处理器使用 IEEE 754 标准定义 double 类型,所以直接将给定的 01 数据存入内存,并让处理器以 double 的形式解析这段内存即可(强制转换为 double 指针,然后解引用)。
#import<bits/stdc++.h>
using namespace std;
main(int t, bitset<64> B) {
cin >> t;
while (t--) {
cin >> B;
auto x = B.to_ullong();
printf("%.15e\n", *(double*)&x);
}
}
直接模拟的代码:
#include <bits/stdc++.h>
using namespace std;
using ld = double;
using ull = unsigned long long;
ull getull(string s) {
bitset<64> B(s);
return B.to_ullong();
}
void solve() {
string s;
cin >> s;
string sign = s.substr(0, 1);
string exponent = s.substr(1, 11);
string fraction = s.substr(12, 52);
ull exp = getull(exponent), frc = getull(fraction);
if (exp == 2047) {
if (frc == 0)
cout << (sign == "0" ? "inf" : "-inf") << '\n';
else
cout << "nan\n";
} else if (exp == 0) {
ld ans = (sign == "0" ? 1 : -1);
ld mid = ld(frc) / pow(2, 52);
ans = ans * mid * pow(2, -1022);
cout << scientific << setprecision(15) << ans << '\n';
} else {
ld ans = (sign == "0" ? 1 : -1);
ld mid = ld(1) + ld(frc) / pow(2, 52);
ans = ans * mid * pow(2, int(exp) - 1023);
cout << scientific << setprecision(15) << ans << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--) {
solve();
}
}
C. Look and Say
作为一个结果序列,序列长度一定是偶数,并可以分成若干个长度为 2 的子串,每个子串的第一位表示对应字串的第二位数字有多少个。遍历所有的子串,就可以模拟出上一个字串的内容。记录模拟到只剩一个 "1" 时的次数就是答案。
#import<bits/stdc++.h>
using namespace std;
main(int t){
cin>>t;
while(t--){
string s,t;
int n=1,i,j;
for(cin>>s;s!="1";++n){
t="";
for(i=0;i<s.size();i+=2)
t+=string(s[i]-'0',s[i+1]);
s=t;
}
cout<<n<<'\n';
}
}
D. Xor Division
分为两种情况,整个序列异或值为 0 或者整合序列异或值为 x(x>0)。
假如整个序列的异或值为 0,那么一定存在一种划分方案将序列分为两段因为 x⨁x=0,其实随便选择一个位置划分就行。
那么假设整个序列的异或值为 x,这时候只能把序列分为奇数段(k≥3)且每段异或和为 x。
对于第二种情况,贪心地检查是否存在一个划分的方法即可。
#include <bits/stdc++.h>
using namespace std;
main() {
int t;
cin >> t;
while (t--) {
int n, s = 0, m;
cin >> n;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++) cin >> a[i], a[i] ^= a[i - 1];
m = a[n];
for (int i = 1; i <= n; i++) {
if (a[i] == m)
++s, m ^= a[n];
}
cout << (a[n] == 0 || s >= 3 ? "YES\n" : "NO\n");
}
}
E. 结构体
代码应该写的很清楚了,略,原题见 P9754 CSP-S 2023] 结构体 - 洛谷。