題目鏈接:https://codeforc.es/contest/1494/problem/C
You are playing a game similar to Sokoban on an infinite number line. The game is discrete, so you only consider integer positions on the line.
You start on a position 0. There are n boxes, the i-th box is on a position ai. All positions of the boxes are distinct. There are also m special positions, the j-th position is bj. All the special positions are also distinct.
In one move you can go one position to the left or to the right. If there is a box in the direction of your move, then you push the box to the next position in that direction. If the next position is taken by another box, then that box is also pushed to the next position, and so on. You can’t go through the boxes. You can’t pull the boxes towards you.
You are allowed to perform any number of moves (possibly, zero). Your goal is to place as many boxes on special positions as possible. Note that some boxes can be initially placed on special positions.
Input
The first line contains a single integer t (1≤t≤1000) — the number of testcases.
Then descriptions of t testcases follow.
The first line of each testcase contains two integers n and m (1≤n,m≤2?105) — the number of boxes and the number of special positions, respectively.
The second line of each testcase contains n distinct integers in the increasing order a1,a2,…,an (?109≤a1<a2<?<an≤109; ai≠0) — the initial positions of the boxes.
The third line of each testcase contains m distinct integers in the increasing order b1,b2,…,bm (?109≤b1<b2<?<bm≤109; bi≠0) — the special positions.
The sum of n over all testcases doesn’t exceed 2?105. The sum of m over all testcases doesn’t exceed 2?105.
Output
For each testcase print a single integer — the maximum number of boxes that can be placed on special positions.
分析
正數部分和負數部分分開來考慮,
對于每一個特殊位置(該位置上沒有箱子),我們都嘗試將箱子正好推到這個位置,這樣這個特殊點前面的所有箱子會從這個點向前延伸出去,然后看這部分延伸會碰到多少特殊位置即可,最后加上特殊點上本來就有箱子的個數(可用二分來找,具體看代碼),維護一個最大值,
負數部分和正數部分相加即是答案,
代碼
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define N 200005
int n,m;
int input[N],a1[N],b1[N],a2[N],b2[N],cnt11,cnt12,cnt21,cnt22;
map<int,int> mp;
int solve(int a[],int b[],int lena,int lenb)
{
int res = 0;
mp.clear();
int mh = 0;
for(int i=1;i<=lena;i++) mp[a[i]] = 1;
for(int i=1;i<=lenb;i++) if(mp[b[i]] == 1) mh++;
res = mh;
for(int i=1;i<=lenb;i++)
{
if(mp[b[i]] == 1)
{
mh--;
continue;
}
int sum = upper_bound(a + 1, a + 1 + lena, b[i]) - a - 1;
int pos = lower_bound(b + 1, b + 1 + lenb, b[i] - sum + 1) - b;
res = max(res, mh + i - pos + 1);
}
return res;
}
int main()
{
int Case = 1;
scanf("%d",&Case);
while(Case--)
{
cnt11 = cnt12 = cnt21 = cnt22 = 0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&input[i]);
if(input[i] > 0) a1[++cnt11] = input[i];
}
for(int i=n;i>=1;i--)
{
if(input[i] < 0) a2[++cnt12] = -1 * input[i];
}
for(int i=1;i<=m;i++)
{
scanf("%d",&input[i]);
if(input[i] > 0) b1[++cnt21] = input[i];
}
for(int i=m;i>=1;i--)
{
if(input[i] < 0) b2[++cnt22] = -1 * input[i];
}
int ans = 0;
ans += solve(a1, b1, cnt11, cnt21);
ans += solve(a2, b2, cnt12, cnt22);
printf("%d\n",ans);
}
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/265973.html
標籤:其他
上一篇:SSM框架整合【圖文詳解】
