ACM: uva 1468 - Restaurant

Restaurant

Mr. Kim is planning to open a new restaurant. His city is laid out as a grid with size M x M. Therefore, every road is horizontal or vertical and the horizontal roads (resp., the vertical roads) are numbered from 0 to M - 1. For profitability, all restaurants are located near road junctions. The city has two big apartments which are located on the same horizontal road. The figure below shows an example of a city map with size 11 x 11. A circle represents an existing restaurant and a circle labeled with `A' or `B' represents the location of an apartment. Notice that a restaurant is already located at each apartment. Each road junction is represented by the coordinate of the ordered pair of a vertical road and a horizontal road. The distance between two locations (x1y1and (x2y2is computed as x1 x2| + | y1 y2|. In the figure below, the coordinates of A and B are (0, 5) and(10, 5), respectively.

ACM: <wbr>uva <wbr>1468 <wbr>- <wbr>Restaurant

 

Mr. Kim knows that the residents of the two apartments frequently have a meeting. So, he thinks that the best location of a new restaurant is halfway between two apartments. Considering lease expenses and existing restaurants, however, he can't select the optimal location unconditionally. Hence he decides to regard a location satisfying the following condition as a good place. Let dist(pqbe the distance between p and q.

A location p is a good place if for each existing restaurant's location qdist(pA) <<I>dist(qAor dist(pB) < dist(qB). In other words, p is not a good place if there exists an existing restaurant's location q such that dist(pA) dist(qAand dist(pB) dist(qB).

In the above figure, the location (7, 4) is a good place. But the location p = (4, 6) is not good because there is no apartment which is closer to p than the restaurant at q = (3, 5), i.e., dist(p,A) = 5 dist(qA) = 3 and dist(pB) = 7 dist(qB) = 7. Also, the location (0, 0) is not good due to the restaurant at (0, 5). Notice that the existing restaurants are positioned regardless of Mr. Kim's condition.

Given n locations of existing restaurants, write a program to compute the number of good places for a new restaurant.

Input 

Your program is to read the input from standard input. The input consists of T test cases. The number of test cases T is given in the first line of the input. Each test case starts with a line containing two integers M and n 2 M 60, 000 and 2 n 50, 000), which represent the size of a city map and the number of existing restaurants, respectively. The (i + 1)-th line of a test case contains two integers xi and yi i = 1, 2,..., n and 0 xiyi M), which represents the coordinate of the i-th existing restaurant. Assume that all restaurants have distinct coordinates and that the two apartments A and B are positioned at the locations of 1-st restaurant and 2-nd restaurant. Notice that A and B are placed on the same horizontal line.

Output 

Your program is to write to standard output. Print exactly one line for each test case. Print the number of good places which can be found in a given city map.

The following shows sample input and output for two test cases.

Sample Input 

2
6 3
1 3
4 3
0 2
11 11
0 5
10 5
4 9
2 8
7 8
5 6
3 5
5 3
3 2
7 2
9 1

Sample Output 

2
16

题意:在一个M*M的矩形范围内, 有着A,B两间apartment, 有n-2间restaurant, 现在要你新建一件restaurant,

     要求你的restaurant要么比其它的restaurant靠近A, 要么比其它的restaurant靠近B. 距离是哈密顿距离.

     要你计算出有多少个位置适合间这样的一间restaurant.

 

解题思路:

     1. A,B在同一纵坐标, 横坐标的上下界是A,B的横坐标, 从左到右根据横坐标进行扫描, 找出每个横坐标

        出现的大于A,B纵坐标的做小纵坐标和小于A,B纵坐标的最大纵坐标.(靠近AB直线).

     2. 从两个方向一次扫描合法的区域, 统计合法位置数量即可.

 

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define min(a,b) (a)<(b)?(a):(b)
#define max(a,b) (a)>(b)?(a):(b)
#define MAX 60005
typedef long long ll;
const int INF = (1<<29);

int M, n;
int y[MAX], miny[MAX], maxy[MAX];
int xa, ya, xb, yb;

inline void swap(int &a, int &b)
{
 int temp = a;
 a = b;
 b = temp;
}

int main()
{
// freopen("input.txt", "r", stdin);
 int caseNum, i;
 scanf("%d", &caseNum);
 while(caseNum--)
 {
  scanf("%d %d", &M, &n);
  scanf("%d %d %d %d", &xa, &ya, &xb, &yb);
  if(xa > xb) swap(xa, xb);

  for(i = xa+1; i < xb; ++i)
  {
   miny[i] = INF;
   maxy[i] = -INF;
  }

  int tx, ty;
  for(i = 2; i < n; ++i)
  {
   scanf("%d %d", &tx, &ty);
   if(ty >= ya) miny[tx] = min(ty, miny[tx]);
   if(ty <= ya) maxy[tx] = max(ty, maxy[tx]);
  }

  y[xa] = 0;
  for(i = xa+1; i < xb; ++i)
   y[i] = min(miny[i]-ya, ya-maxy[i]);
  for(i = xa+1; i < xb; ++i)
   y[i] = min(y[i-1]+1, y[i]);
  y[xb] = 0;
  for(i = xb-1; i > xa; --i)
   y[i] = min(y[i+1]+1, y[i]);

  ll ans = 0;
  for(i = xa+1; i < xb; ++i)
  {
   if(y[i])
   {
    ans++;
    ans += min(y[i]-1, M-1-ya);
    ans += min(y[i]-1, ya);
   }
  }

  printf("%lld\n", ans);
 }

 return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值