P8073 [COCI2009-2010#7] BAKICE题解 转存洛谷

题目

-----迷人的分割线-------

题意

“如果多个乘客到某座位的距离最近且相同那么将会产生爆炸事件”。


可以这么认为一个座位让这些人一起坐上去,至于爆炸的次数,只需要最后统计哪些位子坐的人超过 1 即可,不用在代码别的地方进行操作。


“发生了多少次爆炸事故”。


其实就是:某个结果中所有的乘客到位子的"边"信息都检查了一遍后,统计有几个座位是多人坐一块儿的。


注意事项

阅读完题目后,我们发现需要使用结构体去存乘客到每个座位的距离。

如果说,只是每个乘客单独存好到各个位子的距离,并且位子那里也存一份每个人到此位子的距离(供双方比较用),然后排完序,根据最近原则安排座位,这会导致一个问题,如下。


4 9
...X.X...
.........
....L....
.....XL..

相比于最上面那两个乘客,乘客 (4,6) 到两个位子都是最近的,安排好了乘客 (4,6) 到位子 (4,7) 后,由于 2<5,对于 (3,5) 这个位子,该怎么办呢?

总不能让 (4,6) 坐两个位子吧,所以我们一定要对所有的边进行排序,如果只是单独存好,就会出现脚踏 n 条船的事故。


做题思路

  1. :首先使用结构体,把每个乘客每个位子的坐标存下来,注意几个乘客几个位子都要统计清楚。

  1. :创一个大的结构体,专门来储存这些“边”的信息,并且使用 sort 排序排好。

  1. :对最近的乘客进行安排,对乘客分析:

第一种情况:乘客没有就坐,目标位置没有被坐。

第二种情况:乘客没坐,目标位置有人,此时只要比较距离即可。

代码实现

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
char ma[105][105];
struct node {
	int id;
	int hang,line;
};
int p1,s1, r,c,num=0;;;//乘客数,座位数
vector<node>p;
vector<node>s;
int pass[10010];//防止脚踏n条船
int seats[10010];//位子序号,值表示坐了几个人。
int dis[10010];
struct node1 {
	int lai;//乘客id
	int qu;//位子id
	int dis;
} e[10010];
//这是存边的结构体 ,即上面说的大的结构体专门存信息”。
bool cmp(node1 a,node1 b) {
	return a.dis<b.dis;
}
//返回-1,会进行交换,0和1是不换的
int main() {
	cin>>r>>c;
	for(int i=1; i<=r; i++) {
		for(int j=1; j<=c; j++) {
			cin>>ma[i][j];
			if(ma[i][j]=='L')s1++,s.push_back((node) {
				s1,i,j
			});
			if(ma[i][j]=='X')p1++,p.push_back((node) {
				p1,i,j
			});
		}
	}
	int step=1;
	for(auto i:p) {
		for(auto j:s) {
			e[step].dis=(i.hang-j.hang)*(i.hang-j.hang)+(i.line-j.line)*(i.line-j.line);
			e[step].lai=i.id;
			e[step].qu=j.id;
			step++;
		}
	}
	step--;  //最后一条边读了还会++一次
	sort(e+1,e+1+step,cmp);
	//从人进行分析!
	for(int i=1; i<=step; i++) {
		if(!pass[e[i].lai]) { //这个人有没有坐,有就下一次循环了。
			if(!seats[e[i].qu]) { //座位没有被坐过 。
				seats[e[i].qu]++;//这个座位人+1
				pass[e[i].lai]=1;//标记人。
				dis[e[i].qu]=e[i].dis;//最近距离。
			} else if(e[i].dis==dis[e[i].qu]&&seats[e[i].qu]) { //座位已经被坐了,然而这个人还没找到位子坐,决定拼下座位。
				seats[e[i].qu]++;
				pass[e[i].lai]=1;
			}
		}
	}
	for(int i=1; i<=s1; i++)if(seats[i]>1)num++;
	cout<<num;
	return 0;
}

最后


送上三组数据方便大家自测自己的代码

10 10
XLX....XLX     
..........
XLX....XXX
..........
..........
..........
..........
..........
XXL.......
..........
3
5 5
X...X
..... 
..L..
.....
X...X
1

10 10
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXLXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
1


题外话,感谢观看,第一次写题解,有点开心!

此题做了很久很久,也踩了很多坑,分享一些心得及见解,第一次写题解(但第 n 次交了),可能写的不好还望海涵,希望管理大大给个过吧,谢谢!题解现在不好找了,以前记得写题解机会很多很多的。

posted @   想念不动声色  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示