题意:有一个M*M的网格,坐标[0...M-1,0...M-1] 网格里面有两个y坐标相同的宾馆A和B,以及n个餐厅,宾馆AB里面各有一个餐厅,编号1,2,其他餐厅编号3-n,现在你打算新开一家餐厅,需要考察一下可能的位置,一个位置p是“好位置”的条件是:当且仅当对于已有的每个餐厅q,要么p比q离A近,要么p比q离B近,即dist(p,A) < dist(q,A) 或者 dist(p,B) < dist(q,B) 问“好位置”的个数
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<queue> #include<stack> #include<string> #include<map> #include<set> #define eps 1e-6 #define LL long long using namespace std; const int maxn = 50000 + 50; const int maxm = 60000 + 50; const int INF = 0x3f3f3f3f; int borderl[maxm], borderr[maxm], rest[maxm]; int m, n, begx, endx, level;//begx,endx记录ab的横坐标 void init() { memset(rest, -1, sizeof(rest)); cin >> m >> n; int tx, ty; cin >> tx >> ty; rest[tx] = ty; begx = tx; cin >> tx >> ty; rest[tx] = ty; endx = tx; if(begx > endx) swap(begx, endx); level = ty; for(int i = 3; i <= n; i++) { cin >> tx >> ty; if(ty < level) ty = 2*level - ty; if(rest[tx] != -1) rest[tx] = min(rest[tx], ty); else rest[tx] = ty; } } void solve() { int ans = 0; borderl[begx] = borderl[endx] = level; borderr[begx] = borderr[endx] = level; for(int i = begx + 1; i < endx; i++) { if(rest[i] != -1) { borderl[i] = min(borderl[i-1]+1, rest[i]); } else { borderl[i] = borderl[i-1] + 1; } } for(int i = endx - 1; i > begx; i--) { if(rest[i] != -1) { borderr[i] = min(borderr[i+1]+1, rest[i]); } else { borderr[i] = borderr[i+1] + 1; } } for(int i = begx + 1; i < endx; i++) ans += max(0, min(min(borderl[i], borderr[i]), m)-max(max(2*level-borderl[i], 2*level-borderr[i]), -1)-1); cout << ans << endl; // for(int i = begx + 1; i < endx; i++) cout << min(borderl[i], borderr[i]) << " " << rest[i] << endl; } int main() { //freopen("input.txt", "r", stdin); int t; cin >> t; while(t--) { init(); solve(); } }
时间: 2024-10-12 19:32:35