题目链接:
传送门
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#define ll long long
using namespace std;
const int N = 50010;
//创建一个结点,包含x,y两坐标和出现的次数w
struct Node {
int u, v, w;
} nodes[N];
int ca, t, m, n, q, k;
//按x来排序
bool cmpx(Node a, Node b) {
return a.u < b.u;
}
//按y来排序
bool cmpy(Node a, Node b) {
return a.v < b.v;
}
int main() {
scanf("%d", &t);
while(t--) {
int cnt = 0;
scanf("%d%d%d", &m, &n, &q);
//输入数据
for(int i = 0; i < q; i++) {
scanf("%d%d%d", &nodes[i].u, &nodes[i].v, &nodes[i].w);
cnt += nodes[i].w;
}
//求出点数的一半,等方便找中位数
int len = cnt / 2;
//判断当前点有奇数个还是偶数个
int oe = cnt % 2;
//一个记录x坐标的中位数,一个记录y坐标的中位数
int ansx, ansy;
//先找x的中位数
sort(nodes, nodes + q, cmpx);
int i = -1, idx = 0;
//寻找中间位
while(idx < len) idx += nodes[++i].w;
//判断当前点数是奇数还是偶数
//奇数直接取中间点
if(oe) {
if(nodes[i].w == 1) ansx = nodes[i + 1].u;
else ansx = nodes[i].u;
//偶数取中间两点的平均值
} else {
if(nodes[i].w == 1) ansx = (nodes[i + 1].u + nodes[i].u) / 2;
else ansx = nodes[i].u;
}
//找y的中位数
sort(nodes, nodes + q, cmpy);
i = -1, idx = 0;
//寻找中间位
while(idx < len) idx += nodes[++i].w;
//判断当前点数是奇数还是偶数
//奇数直接取中间点
if(oe) {
if(nodes[i].w == 1) ansy = nodes[i + 1].v;
else ansy = nodes[i].v;
//偶数取中间两点的平均值
} else {
if(nodes[i].w == 1) ansy = (nodes[i + 1].v + nodes[i].v) / 2;
else ansy = nodes[i].v;
}
//输出答案
printf("Case %d: %d %d\n", ++k, ansx, ansy);
}
}
这道题是一个找中位数的题只要分别找以下x坐标和y坐标的中位数即可。
首先存下所有点的坐标以及对应的点的个数,然后根据x和y排序,寻找分别寻找他们的中位数,最后输出答案即可。
找中位数时要分情况讨论第一种是序列长度为奇数的序列,这种序列直接找到中间的那个值即可,接下来就是序列长度为偶数的序列,这种情况下我们找到最靠中间的那两个数,然后将那两个数求一个平均数即为答案。