TZOJ 4471: Postman FJ
描述
FJ now is a postman of a small town in the hills. The town can be represented by a N×N matrix. Each field is represented with:
-'K' character: a house;
-'P' character: the post office;
-'.' character: a pasture.
Moreover, each field is assigned with an altitude.
Each day, FJ starts at the single post office of the town, and has to deliver mail to all houses in the town. He can move horizontally, vertically and diagonally to adjacent squares. When he delivers all mails, he must return to the post office.
Now, we define the "tiredness" as the difference between the heights of the highest and the lowest field during the delivering. Tell FJ the minimal tiredness to deliver all the mail.
输入
The first line has an integer N (2 ≤ N ≤ 50), then follows 2*N lines. For the first N lines, each lines has N characters (can be 'P', 'K', '.' characters and 'P' appears exactly once, and 'K' appears at least once) . The next N lines each contain N positive integers indicating the corresponding altitudes of the N*N fields.
Each integer is less than 1000000.
输出
Output one integer indicating the minimum possible tiredness.
样例输入
2
P.
.K
2 1
3 2
样例输出
0
题意:
给一个n*n的矩阵,每个点都有一个高度,图中有一个邮局和若干个房子,求邮递员以邮局为起点途径所有房子并返回起点所经过的点的高度差(最大值-最小值)最小。
邮递员每次可以向周围八个方向移动一格。
题目分析:
首先可以知道只有最多2500个点,我们可以先枚举高度最小值,然后二分它的最大值,二分过程中用bfs判能不能从起点到所有房子。复杂度为:n^4*log(n^2)。
#include <bits/stdc++.h> using namespace std; const int N=55; char s[N][N]; int dx[]={-1,-1,-1,0,0,1,1,1},dy[]={-1,0,1,-1,1,-1,0,1}; vector<int> G[N*N],A,B; int h[N*N],n,S; bool vis[N*N]; bool check(int l,int r) {//判断从起点开始只经过高度[l,r]能否到达所有房子 if(h[S]<l||h[S]>r) return false; for(int i=0;i<n*n;i++) vis[i]=false; queue<int> qu; qu.push(S),vis[S]=true; while(!qu.empty()) { int u=qu.front();qu.pop(); for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(h[v]<l||h[v]>r||vis[v]) continue; qu.push(v),vis[v]=true; } } for(int i=0;i<A.size();i++) { if(!vis[A[i]]) return false; } return true; } int main() { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%s",s[i]); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { scanf("%d",&h[i*n+j]); B.push_back(h[i*n+j]);//存所有的高度 if(s[i][j]=='P') S=i*n+j;//起点 else if(s[i][j]=='K') A.push_back(i*n+j);//存所有的房子 } } for(int i=0;i<n;i++) {//建图 for(int j=0;j<n;j++) { for(int k=0;k<8;k++) { int xx=i+dx[k],yy=j+dy[k]; if(xx<0||xx>=n||yy<0||yy>=n) continue; G[i*n+j].push_back(xx*n+yy); } } } sort(B.begin(),B.end()); int up=B.size(),mn=0x3f3f3f3f; for(int i=0;i<up;i++) {//枚举最小值 int L=i,R=up-1,ans=-1;//二分最大值 while(L<=R) { int mid=(L+R)>>1; if(check(B[i],B[mid])) ans=mid,R=mid-1; else L=mid+1; } if(ans!=-1) mn=min(mn,B[ans]-B[i]); } printf("%d\n",mn); return 0; }
原文地址:https://www.cnblogs.com/zdragon1104/p/11877406.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Servlet API 源码剖析
- Borg:Google集群管理大杀器
- 一文了解Zookeeper
- 【投稿】刀哥:Rust学习笔记 4
- Spring Boot 运行源码剖析
- Spring Boot 特性之 Lazy
- Spring Boot 特性之 Banner
- Spring Boot 特性之 Fluent Builder API
- 一文搞懂 Flink Timer
- DATE类型的“小陷阱”
- 简单聊下 Java Agent
- Byte Buddy 基础知识
- 两种在SAP Cloud Application Studio里通过编程对C4C UI字段赋值的方法
- 如何使用 BTrace v.2.0.1
- 三分钟写一个 Java 多线程