AtCoder Beginner Contest 203(Sponsored by Panasonic)(补题)
Posted 佐鼬Jun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Beginner Contest 203(Sponsored by Panasonic)(补题)相关的知识,希望对你有一定的参考价值。
A - Chinchirorin
#include <bits/stdc++.h>
using namespace std;
int a, b, c;
int main() {
scanf("%d%d%d", &a, &b, &c);
if (a == b)
printf("%d\\n", c);
else if (a == c)
printf("%d", b);
else if (b == c)
printf("%d\\n", a);
else
printf("0");
}
B - AtCoder Condominium
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, k;
scanf("%d%d", &n, &k);
int res = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= k; j++) {
res += 100 * i + j;
}
}
cout << res << endl;
return 0;
}
前两题都是签到题,从第三题开始才有意思
C - Friends and Travel costs
题意 就是人在数轴上,从i走到(i+1)要消耗1元,起始状态你有k元,你有n个朋友,在一些点,遇到朋友,他们会给你钱,当钱为0元时,就不能再走了,问你最多能走到多远。
思路 : 肯定不能一个一个点的走,数据范围很大,会超时。要开map或者pair,根据点来排序,能走到朋友点,就走过去零钱,走不到就根据现有的钱走到一个点,当没有朋友时,也是看自己的剩余钱,来判断走到哪。数据范围非常大,还要注意long long的问题
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n, k;
map<ll, ll> M;
int main() {
scanf("%lld%lld", &n, &k);
for (int i = 1; i <= n; i++) {
ll x, v;
scanf("%lld%lld", &x, &v);
M[x] = M[x] + v;
}
ll res = 0;
for (auto i : M) {
if (k - (i.first - res) >= 0) {
k -= (i.first - res);
res = i.first;
k += i.second;
} else {
break;
}
}
if (k > 0) res += k;
cout << res << endl;
}
D - Pond
题意: 给你一个N×N的矩阵,让你挖出K×K的矩阵,让你求出所有K×K矩阵里的中位数(题目给的定义),并求出众多中位数中的最小值。题目说中位数就是第⌊K2/2⌋+1 个数,就是所谓的中位数。
思路:把原矩阵转化为0/1矩阵,大于等于x的都为1,小于的都为0。x的设置就利用二分来一个一个找,然后就看矩阵中的和是否大于等于⌊K2/2⌋+1.
是的话,说明这个x在K×K矩阵比里面的中位数(题目定义的)小于或等于。
否的话,说明这个x比K×K矩阵里面的中位数还大,不符合题意,找的数太大了,比中位数还大。
可以证明,二分出来的答案就是正确答案
x如果比正确答案还小,那么 L 还不等于 R,说明正确答案还在[L,R]之间 ,那就继续二分[L,R]区间就行,一定能二分出在[L,R]里的正确答案。
x如果比正确答案还大,那么肯定会出现,哪个K×K矩阵里面的0/1求和小于⌊K2/2⌋+1(x比正确答案还大,含有正确答案的那个矩阵,x比那个正确答案大,导致对应位置是0,从而求和小于⌊K2/2⌋+1.),导致进入false,从而减小x
#include <bits/stdc++.h>
using namespace std;
int n, k;
const int N = 888;
int a[N][N]; //原矩阵
int s[N][N]; //0/1前缀和矩阵
bool check(int x) {
//转化为0/1矩阵,根据与x的大小关系
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + (a[i][j] >= x);
}
}
//求出不同K*K矩阵下的前缀和,两层for循环,就是矩阵的偏移量,i控制上下,j控制左右
for (int i = k; i <= n; i++) {
for (int j = k; j <= n; j++) {
if (s[i][j] - s[i - k][j] - s[i][j - k] + s[i - k][j - k] < (k * k / 2) + 1)
return false;
}
}
return true;
}
int main() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
scanf("%d", &a[i][j]);
}
}
int l = 0, r = 1e9;
while (l < r) {
int mid = (l + r + 1) >> 1;
if (check(mid))
l = mid;
else
r = mid - 1;
}
printf("%d\\n", l);
return 0;
}
To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激
以上是关于AtCoder Beginner Contest 203(Sponsored by Panasonic)(补题)的主要内容,如果未能解决你的问题,请参考以下文章
AtCoder Beginner Contest 115 题解