2022.7.8学校个人赛(?)部分题目+解
作者:互联网
学校拉的一些比赛题目
A. Drazil and Date
题意:给定一个点的坐标和步数\(s\),求从点\((0, 0)\)到这个点能不能恰好在\(s\)步完成
分析:这个蛮简单的,因为可以走回头路,也就是说每2步可以被“浪费”,就是要注意点坐标的值可以是负数。所以,用总步数减去两点坐标差再判断多余部分是否是偶数就行了(当然,要是步数不够也是不行的)
代码:
#include <iostream>
#include <algorithm>
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
i64 a, b, m;
cin >> a >> b >> m;
a = abs(a);
b = abs(b);
if ((m - a - b) % 2 == 1 || m - a - b < 0) {
cout << "No\n";
} else {
cout << "Yes\n";
}
return 0;
}
B. Balls Game
链接:Problem - 430B - Codeforces
题意:规则类似祖玛,三个颜色相同的球相邻就会被消除,现在手上有一个颜色为\(k\)的的球,求最多能消除多少个球
解析:先“合并同类项”,不然会TLE,这部分的代码如下(借鉴了jls的):
vector<array<int, 2>> arr;
for (int i = 0; i < n; i++) {
int t = a[i];
if (arr.empty() || t != arr.back()[0]) {
arr.push_back({t, 1});
} else {
arr.back()[1]++;
}
}
然后就是简单的双指针,定义一个l和r再往两边走就好了,不要忘了边界特判,完整代码如下:
#include <iostream>
#include <algorithm>
#include <vector>
#include <array>
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, k, x;
cin >> n >> k >> x;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
vector<array<int, 2>> arr;
for (int i = 0; i < n; i++) {
int t = a[i];
if (arr.empty() || t != arr.back()[0]) {
arr.push_back({t, 1});
} else {
arr.back()[1]++;
}
}
int m = arr.size();
int ans = 0;
for (int i = 0; i < m; i++) {
if (arr[i][0] == x && arr[i][1] >= 2) {
int tmp = arr[i][1];
int l = i - 1, r = i + 1;
while (arr[l][0] == arr[r][0] && arr[l][1] + arr[r][1] >= 3 && l >= 0 && r < n) {
tmp += arr[l][1] + arr[r][1];
l--;
r++;
}
ans = max(ans, tmp);
}
}
cout << ans;
return 0;
}
C. Drazil and Factorial
链接:Problem - 515C - Codeforces
题意:给定一个长为\(n\)的数字\(a\),可能有前导零。定义\(F(x)\)为\(x\)的各个数字的阶乘的积,求满足\(F(x) = F(a)\)的最大整数\(x\)
分析:样例再草稿纸上写一遍就明了了,记\(a_i\)为某一位数字,记录一下$ [1, a_i]\(中整数出现的次数,其中\) 9\(要拆成\) 3\times 3\(,\) 6$拆成 $ 2 \times 3\(,\) 4\(拆成\) 2 \times 2$。
接着从最大的一位数开始枚举,每次枚举就减去响应的一位数字的出现次数。注意到一定会有一组解。代码如下:
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
// int fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
int n;
cin >> n;
string s;
cin >> s;
map<int, int>digs;
for (int i = 0; i < n; i++) {
int x = s[i] - '0';
for (int j = 1; j <= x; j++) {
if (j == 4) {
digs[2] += 2;
} else if (j == 6) {
digs[2]++;
digs[3]++;
} else if (j == 8) {
digs[2] += 3;
} else if (j == 9) {
digs[3] += 2;
} else {
digs[j]++;
}
}
}
string ans = "";
for (int i = 7; i > 1; i--) {
if (digs.count(i) && digs[i] > 0) {
int cnt = digs[i];
for (int k = 0; k < cnt; k++){
ans.push_back(i + '0');
}
for (int j = i; j > 1; j--) {
if (j == 4) {
digs[2] -= 2 * cnt;
} else if (j == 6) {
digs[2] -= cnt;
digs[3] -= cnt;
} else {
digs[j] -= cnt;
}
}
}
}
cout << ans;
return 0;
}
D. Common Divisors
链接:Problem - 182D - Codeforces
题意:一个字符串$ s\(若能由若干个它的字串\)t\(构成,那么\)t\(就是\)s\(的“约子串”。现给定两个字符串\)s1 ,s2$,求它们的最大约子串。
解析:额……暴力?简单模拟一遍就好了吧……
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s1, s2;
cin >> s1 >> s2;
vector<string> sub1;
sub1.push_back(s1);
for (int i = 1; i <= s1.length() / 2; i++) {
if (s1.length() % i == 0) {
string tmp = s1.substr(0, i);
int t = s1.length() / i;
string tmp2 = tmp;
for (int j = 1; j < t; j++) {
tmp += tmp2;
}
if (tmp == s1) {
sub1.push_back(tmp2);
}
}
}
vector<string> sub2;
sub2.push_back(s2);
for (int i = 1; i <= s2.length() / 2; i++) {
if (s2.length() % i == 0) {
string tmp = s2.substr(0, i);
int t = s2.length() / i;
string tmp2 = tmp;
for (int j = 1; j < t; j++) {
tmp += tmp2;
}
if (tmp == s2) {
sub2.push_back(tmp2);
}
}
}
int ans = 0;
for (auto& ch1 : sub1) {
for (auto& ch2 : sub2) {
if (ch1 == ch2) {
ans++;
}
}
}
cout << ans;
return 0;
}
C. Little Pony and Expected Maximum
链接:Problem - 454C - Codeforces
题意:给定n个有m个面的筛子,同时掷出,求点数的最大数学期望
解析:独立重复实验嘛,高中没好好学现在写题目有点吃力。
以第一组样例为例:
最大值是1的情况有\((1, 1, 1)\)一种
最大值是2的情况有\((2, 1, 1)\)、\((2, 2, 1)\)、\((2, 2, 2)\)三种
最大值是3的情况有5种
……
注意到,\(n\)个数字中若最大值是\(m\),则共有\(n[n^m - (n - 1)^m]\)种情况,于是我们只要累加所有的可能值再除以所有的情况数就可以得到期望值,所以有公式:
考虑到可能会爆double导致精度缺失的情况,上式可变形为:
\[\sum i[(\frac{i}{m})^n - (\frac{i - 1}{m})^n] \]完整代码如下:
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> m >> n;
double ans = 0;
for(int i = 1;i <= m; i++) {
ans += i * ((powf(( 1.0 * i / m ), n)) - (powf((( 1.0 * i - 1) / m), n)));
}
printf("%.12lf", ans);
return 0;
}
标签:arr,题目,int,cin,long,个人赛,using,2022.7,include 来源: https://www.cnblogs.com/isrol/p/16459463.html