版权声明:欢迎读者提问交流。 个人水平有限,表述不当或疏漏之处敬请批评指正。 作者:trialley 来源:CSDN 著作权归作者所有。非商业转载请注明出处,商业转载请联系作者获得授权。 https://blog.csdn.net/lgfx21/article/details/89303911
注:注释和BFS的条件判断部分都写得比较详细
我踩的坑:
- 提交时freopen与cout调试代码不注释
- scanf不智能,修改数据类型时无法自动适应
- 新状态push入队列时不能基于老状态修改,因为老状态需要重复使用
- 多个if嵌套便于理解逻辑
- 各种数据类型的范围
- char
- short
- int=long
- long long
- float
- double
- long double
试题编号: | 201403-4 |
试题名称: | 无线网络 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 目前在一个很大的平面房间里有 n 个无线路由器,每个无线路由器都固定在某个点上。任何两个无线路由器只要距离不超过 r 就能互相建立网络连接。 输入格式 第一行包含四个正整数 n,m,k,r。(2 ≤ n ≤ 100,1 ≤ k ≤ m ≤ 100, 1 ≤ r ≤ 108)。 输出格式 输出只有一个数,即在指定的位置中增设 k 个路由器后,从第 1 个路 由器到第 2 个路由器最少经过的中转路由器的个数。 样例输入 5 3 1 3 样例输出 2 |
#include<cmath>
#include<queue>
#include<math.h>
#include<cstring>
#include<iostream>
#include<cstdio>
#define ll double//long long则提交错误
using namespace std;
/*点数组与图数组*/
ll point[250][2] = { 0 };
char graph[250][250] = { 0 };
typedef struct statu {
int num = 0;//当前节点序号
int nk = 0;//访问过的未定点的个数
int path = 0;//访问过的点的总个数,即步长
}statu;
/*求两点间距离*/
ll distance(ll* a, ll* b) {
return sqrt(pow((a[0] - b[0]), 2) + pow((a[1] - b[1]), 2));
}
int main() {
/*信息输入 */
int n;
int m;
int k;
ll r;
//freopen("in.txt", "r", stdin);//调试代码注释则错误
cin >> n>>m>>k>>r;//输入信息少于10000条,使用cin (cin可以自动判断输入内容与目标变量的格式;scanf不那么智能,但是快
/*点信息输入,输入时一视同仁
之后根据n与m确定哪些是已有点哪些是未定点*/
for (int i = 0; i < (n + m); i++) {
cin>>point[i][0]>>point[i][1];
}
/*计算每个点间的距离(包括两种点)
距离只在这里有用,用完无需保存*/
//由于距离的计算是相互的
//因此j总是以i+1为初始值
for (int i = 0; i < n + m; i++) {
for (int j = i + 1; j < n + m; j++) {
if (distance(point[i], point[j]) <= r) {
graph[i][j] = 1;
graph[j][i] = 1;
}
}
}
/*广度优先搜索*/
char visited[250] = { 0 };//访问标志
visited[0] = 1;
statu now;
now.nk = 0;
queue<statu> q;
q.push(now);
int min = 100000;
while (!q.empty()) {
statu now = q.front();
q.pop();
//条件判断,如果只要求找到目标,则满足条件退出即可
//如果要求求最值,则不能退出,要全部遍历
if (now.num == 1 && now.path < min) {
min = now.path;
//cout<<min<<endl;//调试代码未注释则错误
}
//继续遍历连接的点,步数也加一
for (int i = 0; i < n + m; i++) {
// cout<<i<<endl;
if(graph[now.num][i]==1){//如果连通
if( !visited[i]){//如果点没有访问过
if(i<n){//如果是固定点
statu neww=now;//命名不能为c++关键词
neww.path++;
neww.num=i;
q.push(neww);
visited[i]=1;
}else {//如果是不固定点
if(now.nk<k){//如果没有达到非固定上限
statu neww=now;//命名不能为c++关键词
neww.nk++;
neww.path++;
neww.num=i;
q.push(neww);
visited[i]=1;
} else{//达到非固定上限
continue;
}
}
}
}
}
}
//最后一个被访问的端点是终点,但题中说的是中间经过的路由地数,所以-1
cout<<min-1;
return 0;
}