結果
| 問題 |
No.2897 2集合間距離
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-09-20 22:33:09 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
RE
|
| 実行時間 | - |
| コード長 | 3,363 bytes |
| コンパイル時間 | 2,554 ms |
| コンパイル使用メモリ | 206,424 KB |
| 最終ジャッジ日時 | 2025-02-24 10:26:35 |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 11 RE * 13 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
template<typename T>
class Cumulative2D{ //2次元 まだ洗練されてない.
private:
T op(T a,T b){return a+b;} //基本足し算なので固定.
T inv(T a){return -a;} //ない場合はスルー->rangeans使用不可.
T e(){return 0;}
int h,w;
bool okB = false;
vector<vector<T>> A;
vector<vector<T>> B[4];
public:
void make(vector<vector<T>> &a,bool ope = true){ //ope=累積opをとる.
A = a; h = A.size(),w = A.at(0).size();
if(!ope) return;
for(int i=0; i<h; i++) for(int k=1; k<w; k++) A[i][k] = op(A[i][k-1],A[i][k]);
for(int i=1; i<h; i++) for(int k=0; k<w; k++) A[i][k] = op(A[i-1][k],A[i][k]);
}
void make2(const function<T(T,T)> f){ //Aに対して上下左右から累積fをとりBとする.
//0左上,1右上,2左下,3右下.
okB = true;
for(auto &b : B) b = A;
for(int i=0; i<h; i++) for(int k=1; k<w; k++) B[0][i][k] = f(B[0][i][k-1],B[0][i][k]);
for(int i=1; i<h; i++) for(int k=0; k<w; k++) B[0][i][k] = f(B[0][i-1][k],B[0][i][k]);
for(int i=0; i<h; i++) for(int k=w-2; k>=0; k--) B[1][i][k] = f(B[1][i][k],B[1][i][k+1]);
for(int i=1; i<h; i++) for(int k=w-1; k>=0; k--) B[1][i][k] = f(B[1][i-1][k],B[1][i][k]);
for(int i=h-1; i>=0; i--) for(int k=1; k<w; k++) B[2][i][k] = f(B[2][i][k-1],B[2][i][k]);
for(int i=h-2; i>=0; i--) for(int k=0; k<w; k++) B[2][i][k] = f(B[2][i][k],B[2][i+1][k]);
for(int i=h-1; i>=0; i--) for(int k=w-2; k>=0; k--) B[3][i][k] = f(B[3][i][k],B[3][i][k+1]);
for(int i=h-2; i>=0; i--) for(int k=w-1; k>=0; k--) B[3][i][k] = f(B[3][i][k],B[3][i+1][k]);
}
T rangeans(int a,int b,int c,int d){ //(a,b)を左上,(c,d)を右下の範囲内 a,b<0許可 c,dは範囲内.
//assert(a <= c && b <= d && 0 <= c && c < h && 0 <= d && d < w);
T ret = A.at(c).at(d);
if(a > 0) ret = op(ret,inv(A.at(a-1).at(d)));
if(b > 0) ret = op(ret,inv(A.at(c).at(b-1)));
if(a > 0 && b > 0) ret = op(ret,A.at(a-1).at(b-1));
return ret;
}
T getA(int x,int y){ //x<0,y<0は許容.
assert(x < h && y < w);
if(x >= 0 && y >= 0) return A.at(x).at(y);
return e();
}
T getB(int p,int x,int y){ //同上.
assert(0 <= p && p < 4 && x < h && y < w && okB);
if(x >= 0 && y >= 0) return B[p].at(x).at(y);
return e();
}
vector<vector<T>> allA(){return A;}
vector<vector<T>> allB(int p){assert(0 <= p && p < 4); return B[p];}
};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int N; cin >> N;
vector<pair<int,int>> S(N);
for(auto &[x,y] : S){
int a,b; cin >> a >> b;
a += 999;
x = (a+b),y = (a-b);
}
vector<vector<int>> give(3000,vector<int>(3000));
Cumulative2D<int> Z;
int M; cin >> M;
while(M--){
int a,b; cin >> a >> b;
a += 999;
int x = (a+b),y = (a-b);
give.at(x).at(y) = 1;
}
Z.make(give);
int low = -1,high = 2001;
while(high-low > 1){
int mid = (low+high)/2;
bool ok = true;
for(auto &[x,y] : S) if(Z.rangeans(x-mid,y-mid,x+mid,y+mid)){ok = false; break;}
if(ok) low = mid;
else high = mid;
}
cout << high << endl;
}