The 2024 Sichuan Provincial Collegiate Programming Contest F. Isoball: 2D Version
题目链接:
正经题意:
有一个固定的矩形,一个大小固定的圆沿一个方向运动,问有没有一个时刻圆完全在矩形里。多组数据,其中
1 ≤ T ≤ 104, −106 ≤ x, y, vx , vy lx , ly, rx , ry ≤ 106,1 ≤ r ≤ 106
简而言之:
就是一个球根据一个向量移动,有没有一个时刻能够满足完全在矩形里(这个题意容易懂,没什么好简化的)
思路:
我的思路比较笨,把圆当作一个矩形,因为圆完全在矩形中,其实和以圆心为原点,半径为边长的矩形在矩形中是等价的。
所以我列了3种情况:
1.无法移动
2.x方向向量存在,那么就可以分为两种情况:
[1]将圆的左边移动到和矩形左边共线
[2]将圆的右边移动到和矩形右边共线
3.y方向向量存在,那么就可以分为两种情况:
[1]将圆的上边移动到和矩形上边共线
[2]将圆的下边移动到和矩形下边共线
再根据以上所有情况去考虑是否符合完全包含就可以了。
代码:
代码写的较丑,请见谅
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+27;
void solve(){
double x,y,r,vx,vy;
double lx,ly,rx,ry;
cin>>x>>y>>r>>vx>>vy;
cin>>lx>>ly>>rx>>ry;
if(vx == 0 && vy==0){
if(x+r <= rx && x-r>=lx){
if(y+r <= ry && y-r >= ly){
cout<<"Yes"<<endl;
return ;
}
}
cout<<"No"<<endl;
return ;
}
if(x+r <= rx && x-r>=lx){
if(y+r <= ry && y-r >= ly){
cout<<"Yes"<<endl;
return ;
}
}
if(vx!=0){
double lx_01 = x-r,ly_01 = y-r;
double ry_01 = y+r,rx_01 = x+r;
if(lx_01 <= lx && vx > 0 || lx_01 >= lx && vx<0){
double rectation1 = (lx - lx_01)/vx;
lx_01 += rectation1*vx;
ly_01 += rectation1*vy;
rx_01 += rectation1*vx;
ry_01 += rectation1*vy;
if(lx_01>=lx && lx_01 <= rx){
if(ly_01>=ly && ly_01 <= ry){
if(rx_01>=lx && rx_01 <= rx){
if(ry_01>=ly && ry_01 <= ry){
cout<<"Yes"<<endl;
return ;
}
}
}
}
}
lx_01 = x-r,ly_01 = y-r;
ry_01 = y+r,rx_01 = x+r;
if(rx_01 <= rx && vx > 0 || rx_01 >= rx && vx < 0){
double rectation1 = (rx - rx_01)/vx;
lx_01 += rectation1*vx;
ly_01 += rectation1*vy;
rx_01 += rectation1*vx;
ry_01 += rectation1*vy;
if(lx_01>=lx && lx_01 <= rx){
if(ly_01>=ly && ly_01 <= ry){
if(rx_01>=lx && rx_01 <= rx){
if(ry_01>=ly && ry_01 <= ry){
cout<<"Yes"<<endl;
return ;
}
}
}
}
}
}
if(vy!=0){
double lx_01 = x-r,ly_01 = y-r;
double ry_01 = y+r,rx_01 = x+r;
if(ly_01 <= ly && vy > 0 || ly_01 >= ly && vy < 0){
double rectation1 = (ly - ly_01)/vy;
lx_01 += rectation1*vx;
ly_01 += rectation1*vy;
rx_01 += rectation1*vx;
ry_01 += rectation1*vy;
if(lx_01>=lx && lx_01 <= rx){
if(ly_01>=ly && ly_01 <= ry){
if(rx_01>=lx && rx_01 <= rx){
if(ry_01>=ly && ry_01 <= ry){
cout<<"Yes"<<endl;
return ;
}
}
}
}
}
lx_01 = x-r,ly_01 = y-r;
ry_01 = y+r,rx_01 = x+r;
if(ry_01 <= ry && vy > 0 || ry_01 >= ry && vy < 0){
double rectation1 = (ry - ry_01)/vy;
lx_01 += rectation1*vx;
ly_01 += rectation1*vy;
rx_01 += rectation1*vx;
ry_01 += rectation1*vy;
if(lx_01>=lx && lx_01 <= rx){
if(ly_01>=ly && ly_01 <= ry){
if(rx_01>=lx && rx_01 <= rx){
if(ry_01>=ly && ry_01 <= ry){
cout<<"Yes"<<endl;
return ;
}
}
}
}
}
}
cout<<"No"<<endl;
return ;
}
int main()
{
int t;cin>>t;
while(t--){
solve();
}
return 0;
}