Codeforces Round #674 (Div. 3)
目录
A. Floor Number
大意:
第一层有2个房间,其它层都有x个房间,问第n个房间在第几层
思路:
向上取整即可
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
typedef long long LL;
int t;
int main(){
cin >> t;
while(t--){
int n, x;
cin >> n >> x;
if (n <= 2) cout << 1 << endl;
else{
cout << 1 + ceil((1.0*n - 2) / x) << endl;
}
}
return 0;
}
B. Symmetric Matrix
大意:
给出n种2x2的小矩阵,问能否用这些矩阵组成一个kxk的主对角线对称矩阵
思路:
当k为奇数的时候无解
否则只要有一个小对称矩阵即可,因为可以都用这个小对称矩阵填充
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
typedef long long LL;
int t;
int main() {
cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
int flag = 0;
while (n--) {
int x1, x2, x3, x4;
cin >> x1 >> x2 >> x3 >> x4;
if (x2 == x3) flag = 1;
}
if (flag == 1 && ((m & 1) == 0))
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
C. Increase and Copy
大意:
一个数组一开始只有一个元素1
现在每次可以做一个操作:
选择一个元素使其+1
或者选择一个元素,复制一份加到数组里
问最少用几次操作就可以使得数组元素的和不少于n
思路:
可以想到是先一直使一个元素+1,然后一直复制这个元素即可
最少操作次数可以通过枚举加到几来更新
只需要枚举到sqrt(n)即可
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
typedef long long LL;
int t;
int main() {
cin >> t;
while (t--) {
int n, res = 0x3f3f3f3f;
cin >> n;
for (int i = 1; i <= sqrt(n); i++) {
int tmp = i - 1;
tmp += ceil((1.0 * n - i) / i);
res = min(res, tmp);
}
cout << res << endl;
}
return 0;
}
D. Non-zero Segments
大意:
给出n个数,问至少插入几个数,可以使得数列里面不存在和为0的区间
思路:
利用前缀和,如果\(sum[l-1]=sum[r]\),那么代表l到r这一区间的和为0,所以只需要用map记录一下前缀和即可
注意每次找到区间后要清空map
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
typedef long long LL;
int n, res;
map<LL, int> mp;
int main() {
cin >> n;
LL sum = 0;
mp[0] = 1;
while (n--) {
LL x;
cin >> x;
sum += x;
if (mp[sum]) {
res++;
sum = x;
mp.clear();
mp[0] = 1;
}
mp[sum]++;
}
cout << res << endl;
return 0;
}
E. Rock, Paper, Scissors
大意:
a和b玩石头剪刀布,给出a和b出石头、剪刀、布的数量,问a最少赢多少次,最多赢多少次
思路:
贪心的想,想让a赢得最少,那么就要把它最多数量的那个方法抵消掉,也就是说如果抵消不了剩下的就是最多能赢的次数
赢得最多,只需要让每种出法都尽可能赢最多次即可
(本来写了排序,结果发现不需要....结构体就没删)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
typedef long long LL;
int n;
struct node {
int type;
LL num;
} a[3], b[3], b2[3];
int main() {
cin >> n;
for (int i = 0; i < 3; i++) {
cin >> a[i].num;
a[i].type = i;
}
for (int i = 0; i < 3; i++) {
cin >> b[i].num;
b[i].type = i;
}
LL res2 = 0;
for (int i = 0; i < 3; i++) {
res2 += min(a[i].num, b[(i + 1) % 3].num);
}
LL res1 = 0;
for (int i = 2; i >= 0; i--) {
int tmp = 0;
for (int j = 0; j <= 2; j++) {
if ((a[i].type + 1) % 3 != b[j].type) {
tmp += b[j].num;
}
}
if (tmp < a[i].num) {
res1 = a[i].num - tmp;
}
}
cout << res1 <<' '<<res2<< endl;
return 0;
}
F. Number of Subsequences
大意:
给出一个长度为n的字符串,其中有若干?,?的地方可以填abc中的任意字母
问填完?所得到的字符串集中,有多少个abc子序列
思路:
考虑dp
\(dp[0]\)代表字符串的数量
\(dp[1]\)代表字符串中子序列"a"的数量
\(dp[2]\)代表字符串中子序列"ab"的数量
\(dp[3]\)代表字符串中子序列"abc"的数量
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
const int mod = 1e9 + 7;
typedef long long LL;
int n;
string s;
LL dp[5];
int main() {
cin >> n;
dp[0] = 1;
for (int i = 1; i <= n; i++) {
char x;
cin >> x;
if (x == 'a') dp[1] = (dp[1] + dp[0]) % mod;
if (x == 'b') dp[2] = (dp[2] + dp[1]) % mod;
if (x == 'c') dp[3] = (dp[3] + dp[2]) % mod;
if (x == '?') {
dp[3] = (3 * dp[3] % mod + dp[2]) % mod;
dp[2] = (3 * dp[2] % mod + dp[1]) % mod;
dp[1] = (3 * dp[1] % mod + dp[0]) % mod;
dp[0] = 3 * dp[0] % mod;
}
}
cout << dp[3] << endl;
return 0;
}