https://ac.nowcoder.com/acm/problem/14674
1. 空心木娃娃只有正方体与球两种形状。
2. 正方体娃娃与球体娃娃可以相互套,也可以相同形状之间套。
3. 当两形状相切的时候使能够互相嵌套的,比如半径为2的球体能套在边长为4的正方体中。
4. 所有木娃娃的厚度可以忽略不计。
现在有n个正方体和m个球形的木娃娃,其中第i个正方体娃娃边长为ai
,第j个球形娃娃半径为rj。用这些娃娃组成一个套娃,最多有几层?
数据保证所有正方体边长不相同,所有的圆半径不相同。
输入第一行为一个整数T(1 ≤ T ≤ 25),表示一共有T组测试数据。
对于每组测试数据:
第一行有两个整数n,m(1 ≤ n,m ≤ 105),分别表示正方体和球体的木娃娃数。
第二行有n个整数,其中第i个整数ai(1 ≤ ai ≤ 1e9)代表第i个正方体娃娃的边长。
第二行有?个整数,其中第i个整数ri(1 ≤ ri ≤ 1e9)代表第?个球形娃娃的半径。
输出一个正整数,表示组成的套娃的层数。
全WA代码:
#define it <> ::iterator
#include <unordered_map>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <string>
#include <bitset>
#include <cstdio>
#include <vector>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
using namespace std;
typedef long long ll;//unsigned
const ll nex[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
const ll inf=0x7fffffff;
const ll mod=1e9+7;//记得改scanf
ll T,n,m,a[100001],r[100001],dp[2][100001],a1[100001],r1[100001];
int main(){
cin>>T;
while(T--){
memset(dp,0,sizeof(dp));
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
a1[i]=3*a[i]*a[i];
// dp[0][i]=0;
}
for(int i=1;i<=m;i++){
cin>>r[i];
r1[i]=2*r[i];
// dp[1][i]=0;
}
sort(a+1,a+1+n);
sort(r+1,r+1+m);
sort(a1+1,a1+1+n);
sort(r1+1,r1+1+m);
ll ans=0;
for(int i=1;i<=min(n,m);i++){
ll s=upper_bound(r1+1,r1+1+m,a[i])-r1-1;
ll k=upper_bound(a1+1,a1+1+n,4*r[i]*r[i])-a1-1;
dp[0][i]=max(dp[0][i-1],dp[1][s])+1;
dp[1][i]=max(dp[0][k],dp[1][i-1])+1;
if(s==i)dp[0][i]=max(dp[0][i],dp[1][i]+1);
//cout<<dp[0][i]<<" "<<dp[1][i]<<endl;
}
ll i=min(n,m)+1;
while(i<=n){
ll s=upper_bound(r1+1,r1+1+m,a[i])-r1-1;
dp[0][i]=max(dp[0][i-1],dp[1][s])+1;
i++;
}
while(i<=m){
ll k=upper_bound(a1+1,a1+1+n,4*r[i]*r[i])-a1-1;
dp[1][i]=max(dp[1][i-1],dp[0][k])+1;
i++;
}
cout<<max(dp[0][n],dp[1][m])<<endl;
}
return 0;
}