题目描述
奶牛们建造了一座剧院, 里面有一个长方形的座位区, 一共有行, 每行有个座位。前后左右相邻座位间的距离都相等.。奶牛们希望它们在网上卖的每一张票能有一套程序自动分配座位。
买票者总是想得到最好的票, 所以每一张票都有一个唯一的优先级(即使有一些座位在外行人看来优先级是一样的),优先级规则如下:
1、优先级最高的位置位于的一行中间的这个位置(这个位置最接近舞台,
对眼睛不好)在第一行 ,第 列,并且有最高的优先级。2、最靠近这个位置的座位(直线距离)有第二高的优先级值,下一个接近这个位置的座位有第三高的优先级值,以此类推。
3、所有与这个位置距离相等的座位,在第一行的优先级好于第二行的(以此类推)。
4、如果与这个位置距离相等的座位在同一行,那么在左边的位置的优先级较好(左边舞台上的景色较好!
牵强的理由), 请看下面的图表.
这儿有一个小的 剧院的座位的优先级值的图表:
座位号
1 2 3 4 5 6 7 8 9 10 11
==============================================
5 | 54 50 44 38 32 29 33 39 45 51 55 |
4 | 52 42 34 25 21 18 22 26 35 43 53 |
3 | 48 36 23 14 12 9 13 15 24 37 49 |
2 | 46 30 19 10 5 4 6 11 20 31 47 |
1 | 40 27 16 7 2 1 3 8 17 28 41 |
==============================================
| 舞台 |
==============================================
输入格式
输入有一行,分别表示两个整数: 和 .
输出格式
输出一个 行 列的优先级图表,每个优先级值右对齐5位输出。
样例
输入样例
11 5
输出样例
|---- 54 50 44 38 32 29 33 39 45 51 55
|---> 52 42 34 25 21 18 22 26 35 43 53-----|
|---- 48 36 23 14 12 9 13 15 24 37 49<----|
|---> 46 30 19 10 5 4 6 11 20 31 47 -----|
40 27 16 7 2 1 3 8 17 28 41 <----|
数据范围与提示
分析
首先,定义一个结构体 .
struct node {
int r;
int c;
}seat[10005];
然后,本题 大难点:
1、本道题需要用结构体数组来排序,所以必须要先将其化为一维数组 .如何实现呢 ?
40 27 16 7 2 1 3 8 17 28 41 46 30 19 10 5 4 6 11 20 31 47
// 第二排的第一位置连接上前一排的最后一个座位
可以发现:第 行第 列的位置,即 可以在以为中表示为:
for(int i=0; i<R; i++) {
for(int j=0; j<W; j++) {
seat[i * W + j].r = i;
seat[i * W + j].c = j;
}
}
2、如何计算、比较直线距离? 将其看成一个三角形:
没错 ! 用勾股定理:
可是开根( sqrt )需要考虑精度问题,所以直接用平方,只要平方大,这就意味着这个数本身就大。也就是:
∴ :
bool cmp(node a, node b) {
int dis_x = (x.r - dx) * (x.r - dx) + (x.c - dy) * (x.c - dy); //a² + b²
int dis_y = (y.r - dx) * (y.r - dx) + (y.c - dy) * (y.c - dy); // c²
if(dis_x == dis_y) {
x.c < y.c; //越在前越好
}
else return dis_x < dis_y; //距离越小越好
}
最后,我们要将一维数组重新还原成原来座位的样子,即二维数组 .
ans[seat[i].r][seat[i].c] = i + 1
Finish ...
贴代码
#include "iostream"
#include "algorithm"
#include "iomanip"
const int MAXN = 1e4 + 10;
int dx, dy;
int ans[105][105];
struct node{
int r;
int c;
}seat[MAXN];
bool cmp(node x, node y) {
int dis_x = (x.r - dx) * (x.r - dx) + (x.c - dy) * (x.c - dy);
int dis_y = (y.r - dx) * (y.r - dx) + (y.c - dy) * (y.c - dy);
if(dis_x == dis_y) {
x.c < y.c;
}
else return dis_x < dis_y;
}
int main() {
int W, R;
std::cin >> W >> R;
dx = 0, dy = (W + 1) / 2;
for(int i=0; i<R; i++) {
for(int j=0; j<W; j++) {
seat[i * W + j].r = i;
seat[i * W + j].c = j;//记录行列位置
}
}
std::sort(seat, seat + W * R, cmp);
for(int i=0; i<R*W; i++) {
ans[seat[i].r][seat[i].c] = i + 1; //归位
}
for(int i=R-1; i>=0; i--) {
for(int j=0; j<W; j++) {
std::cout << std::setw(5) << ans[i][j];
}
std::cout << "\n";
}
return 0;
}