开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 13 天,点击查看活动详情
Codeforces Round #663 (Div. 2) A题
题意解析:
输入一个长度n,用1~n的数字进行随机排列。 定义对于一个正整数n,如果对于每一对和都满足, 对于p的每个子数组,其中所有元素的OR不小于该子数列中元素的个数。 我们称长度为的排列是好的。
题解:两个数进行位运算了,且范围是1~n,那么进行位运算后的结果不会小于元素的个数。 简而言之就是:无论怎么输出这个置换序列都是正确的。(我是逆序输出的。)
AC Code
int main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
for (int i = n; i >= 1; i--) printf("%d ",i);
cout << endl;
}
return 0;
}
Codeforces Round #663 (Div. 2) B题
题意解析:
给定一个n×m的传送带,每个位置都有一个字母(R或者D)其中R代表向右,D代表向下。
我们可以通过改变字母,从而改变传送带的方向,将行李运到C的位置。
要使得传送带上的行李 ==都== 能到达C处,求出我们至少要进行多少次操作修改字母。
题解:传送带只能往下和往右,过程中一定会到下边界和右边界。所以要到达C,即右边界的R改成D,下边界的D改成R即可。做法就是,遍历字符:
- 当遍历到右边界的时候,如果该字符是R,则cnt +1(需要改为D)
- 当遍历到下边界的时候,如果该字符是D,则cnt +1(需要改为R)
AC Code
int main() {
int t;
cin >> t;
string str[110];
while (t--) {
int n, m, cnt = 0; //cnt:需要统计的最少修改次数
cin >> n >> m;
for (int i = 0; i < n; i++) cin >> str[i];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++) {
if (str[i][j] == 'D' && i == n - 1) cnt++; //最后一行的D要改成R
if (str[i][j] == 'R' && j == m - 1) cnt++; //最后一列的R要改成D
}
printf("%d\n", cnt);
}
return 0;
}
Educational 88 A题
题意解读:
游戏开始时,每个玩家从牌组中取出张牌(所以每张牌都由一个玩家取出)。拥有最多小丑数量的玩家是赢家,他得到的点数等于x - y,其中x是赢家手中的小丑数量,y是所有其他玩家中小丑的最大数量。如果有两个或更多的玩家有最多的笑话,他们都是赢家,他们得到0分。
题解: 假设,玩家1一定是赢家,他手上拿了尽可能多的小丑牌。
- 如果小丑牌全在玩家手上,那分数就是m;
- 如果小丑牌太多,玩家1拿不完,那剩下的开玩笑牌均摊到其他玩家手上;
总结:思路就是让玩家1的分数最大化,让玩家1手上的小丑牌数量尽可能与其他玩家的拉开差距
考虑特殊情况: 如果m=0,那么无论如何,结果一定为0
AC Code
int main() {
int t;
cin >> t;
while (t--) {
int n, m, k, x = 0, y = 0, res = 0;
cin >> n >> m >> k;
if (m == 0) cout << 0 << endl;//考虑特殊情况m=0时,结果无论如何都是0
else if (n / k >= m) {
//将所有的joker牌(m张)给到玩家1,从而最后的得分就是 m-0 分
res = m;
cout << res << endl;
} else if((m - n / k) >= (k - 1)) {
//joker牌过多,则待玩家1拿完,剩下的其他人均摊
x = n / k;
y = ceil((1.0 * m - n / k) / ( 1.0 * k - 1));//这里有m-n/k不能被k-1整除的情况,可以用ceil向上取整即可
res = x - y;
cout << res << endl;
} else cout << n / k - 1 << endl;
}
return 0;
}