1.Problem J. Breakfast
输出39.20即可,保留两位小数,WA了一发...
#include<iostream>
using namespace std;
int main(){
printf("%.2f", 0.6 * 32 + 20);
return 0;
}
2.Problem A. Paper Watering
开方log(n)级别,次数少,不会超时。当时想法就是,如果开方不能整开开的数,那么他就能构成 (k - 1) + 1个数,如果能整开,平方就不会出现新数。
#include<iostream>
#include<cmath>
using namespace std;
int main(){
std::ios::sync_with_stdio(false);
int n, m;
cin >> n >> m;
if(n == 1){
cout << 1;
return 0;
}
long long res = m + 1;
int x = sqrt(n);
m --;
while(m != 0){
if(x == 1){
n = x;
break;
}
if(x * x != n)
res += m;
res ++;
n = x;
x = sqrt(n);
m --;
}
res ++;
cout << res;
return 0;
}
3.Problem D. nIM gAME
前面都按照最优的拿,到最后只会有1,2,3个石子, 所以都会输...
#include<iostream>
using namespace std;
int main(){
std::ios::sync_with_stdio(false);
int n;
cin >> n;
while(n --){
int x;
cin >> x;
cout << "lose" << endl;
}
return 0;
}
4.Problem E. Checksum
题意为pA + pB = D = B, 所以直接说 pA + pB = B就完全ok,说了一大堆... pA = B - pB,由于pA已知,B最的个数为2^20 - 1, B - pB 单调递增,预处理出来2^20 的 B - pB,二分查找。输出k位
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
int p[2097200];
int pa[2097200];
int res[30];
int main(){
// 20 * 1e6;
std::ios::sync_with_stdio(false);
for(int i = 1; i <= 1048576; i ++){
int t = i;
while(t){
if(t & 1)
p[i] ++;
t = t >> 1;
}
pa[i] = i - p[i];
}
int T;
cin >> T;
for(int i = 0; i < T; i ++){
int n, k;
string s;
cin >> n >> k;
cin >> s;
memset(res, 0, sizeof(res));
// 统计 1 的个数
int cnt = 0;
for(int j = 0; j < n; j ++)
if(s[j] == '1')
cnt ++;
int high = 1; // 多能表示多少 k最小为1
for(int j = 0; j < k; j ++)
high = high << 1;
bool f1 = true;
int f = lower_bound(pa + 1, pa + 1048577, cnt) - pa; // 找到 f 返回下标, 如果找不到 返回2097152
if(f >= high || p[f] != cnt)
f1 = false;
if(f1){
cnt = 1;
while(f){ // 从后往前倒序输出
res[cnt] = f % 2;
cnt ++;
f = f / 2;
}
for(int j = k; j >= 1; j --)
cout << res[j];
cout << endl;
} else
cout << "None" << endl;
}
return 0;
}
5.Problem L. Bracket Generation
这题当时队友想用dfs记忆化搜索,但觉得空间占用巨大,代码量巨大,同时伴随超时风险,就懒得写了,换个思路就简单了很多,对于每一个操作2的可能有操作2出现之后的操作都可以算作一种可能,而1操作只有一种可能,所以总可能数就是每一个2操作可能的乘积。我输入处理我能看懂的...
#include<iostream>
#include<unordered_map>
#include<string>
using namespace std;
long long int mod = 998244353;
int main(){
string s;
cin >> s;
int len = s.size();
int cnt = 0;
string tmp = "";
for(int i = 0; i < len; i ++){
if(i + 1 < len && s[i] == '(' && s[i + 1] == ')'){
tmp += '1';
i ++;
}
else if(s[i] == ')'){
cnt ++;
tmp += '2';
}
}
// 分为1操作和2操作,对于每个2操作的可都都可以是 大于等于2操作出现的之后的每一种肯能,总共由 x个2 操作,
// 他的总共可能性就是每个可能性的乘积
long long res = 1;
len = tmp.size();
for(int i = len - 1; i >= 0; i ++){
if(tmp[i] == '2')
res = res * (len - i) % mod;
}
cout << res;
return 0;
}