题目链接:点这里~
比赛心得:遇到几何不要慌,试试看暴力行不行=。 =
A - Vanishing Pitch
题目大意
v表示小球速度, t s 表示一个时间区间, d表示球距离棒球手的距离
在小球匀速飞行,在[t,s]时间区间内会消失,问棒球手最后能不能击中棒球
思路
求出小球飞到棒球手所花时间d/v,看是否在那个时间段就行
如果怕精度问题可以将时间区间变成距离区间[vt, vs],然后看d是否在区间内就好
ac代码
#include<bits/stdc++.h>
using namespace std;
#define io cin.tie(0);ios::sync_with_stdio(false);
#define debug(x) cout<<#x<<"="<<x<<endl
#define lowbit(x) x&(-x)
#define pii pair<int,int>
#define mk make_pair
#define ll long long
#define rs p<<1|1
#define ls p<<1
const int maxn = 1e6 + 5;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
inline ll read(){
ll p=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){p=(p<<1)+(p<<3)+(c^48),c=getchar();}
return f*p;
}
void solve(){
ll a, b, c, d;
cin >> a >> b >> c >> d;
b *= a; c *= a;
if(d >= b && d <= c) puts("No");
else puts("Yes");
}
int main(){
solve();
return 0;
}
B - Remove It
题目大意
给你长度为n的序列,还有一个m,然后要你去掉序列中所有等于m的数,输出剩下的数
思路
判断留不留,直接用vector存
ac代码
#include<bits/stdc++.h>
using namespace std;
#define io cin.tie(0);ios::sync_with_stdio(false);
#define debug(x) cout<<#x<<"="<<x<<endl
#define lowbit(x) x&(-x)
#define pii pair<int,int>
#define mk make_pair
#define ll long long
#define rs p<<1|1
#define ls p<<1
const int maxn = 1e6 + 5;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
inline ll read(){
ll p=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){p=(p<<1)+(p<<3)+(c^48),c=getchar();}
return f*p;
}
vector<int> ans;
void solve(){
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; i ++){
int x; cin >> x;
if(x == m) continue;
ans.push_back(x);
}
int f = 0;
for(auto it : ans){
if(f) cout << " "; f = 1;
cout << it;
}
}
int main(){
solve();
return 0;
}
D - Circle Lattice Points
题目大意
给你一个圆心坐标和半径,问你该圆包含的整点是多少
思路
虽然是道不擅长的几何题,但是无妨,直接暴力跑整点横坐标,然后求出上下两个纵坐标,然后对上下坐标之间的整点数求和即可,但是精度会损失,所以这里的应对方法是半径R+1e-14
ac代码
#include<bits/stdc++.h>
using namespace std;
#define io cin.tie(0);ios::sync_with_stdio(false);
#define debug(x) cout<<#x<<"="<<x<<endl
#define lowbit(x) x&(-x)
#define pii pair<int,int>
#define mk make_pair
#define ll long long
#define lb long double
#define rs p<<1|1
#define ls p<<1
const int maxn = 1e6 + 5;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
inline ll read(){
ll p=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){p=(p<<1)+(p<<3)+(c^48),c=getchar();}
return f*p;
}
void solve(){
io;
lb x, y, R;
cin >> x >> y >> R;
R += 1e-14;
ll ans = 0;
for(int i = ceil(x - R); i <= floor(x + R); i ++){ //左边界向上取整,有边界向下取整
lb t, b;
t = y + sqrt(R * R - (x - i) * (x - i));
b = y - sqrt(R * R - (x - i) * (x - i));
ans += floor(t) - ceil(b) + 1; //上边界向下取整,下边界向上取整
}
cout << ans << endl;
}
int main(){
solve();
return 0;
}
E - Come Back Quickly
题目大意
n个城市m条道路,每条路ai, bi, ci,表示ai到bi的单项路,需要花费ci分钟走到,可能会有重边和自环。问能否从第i个城市出发然后回到该城市形成一个环?可以输出最短时间,否则-1
思路
时间给了3s,2000个点,直接考虑n个优先队列优化的dijkstra,求出城市i到其他城市的最短路,一个for更新来回跑的最小值。最后看有没有自环,如果有那么存自环的最短时间,然后跟之前更新的最小值当中取较小者。
ac代码
#include<bits/stdc++.h>
using namespace std;
#define io cin.tie(0);ios::sync_with_stdio(false);
#define debug(x) cout<<#x<<"="<<x<<endl
#define lowbit(x) x&(-x)
#define pii pair<int,int>
#define mk make_pair
#define ll long long
#define rs p<<1|1
#define ls p<<1
const int maxn = 2005;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
inline ll read(){
ll p=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){p=(p<<1)+(p<<3)+(c^48),c=getchar();}
return f*p;
}
int dis1[maxn][maxn], vis[maxn];
//dis1表示i到其他城市最短路,vis是自环的最小权值
struct node{
int u, w;
bool operator < (const node &a) const{
return w > a.w;
}
};
vector<node> v1[maxn];
void dij1(int st){
dis1[st][st] = 0;
queue<node> q;
q.push({st, 0});
while(q.size()){
node t = q.front(); q.pop();
int from = t.u;
for(auto it : v1[from]){
int to = it.u, w = it.w;
if(dis1[st][from] + w < dis1[st][to]){
dis1[st][to] = dis1[st][from] + w;
q.push({to, dis1[st][to]});
}
}
}
}
void solve(){
int n, m;
scanf("%d%d", &n, &m);
fill(vis, vis + maxn, inf);
for(int i = 1; i <= m; i ++){
int x, y, w;
scanf("%d%d%d", &x, &y, &w);
if(x == y){
vis[x] = min(vis[x], w);
continue; //自环没必要建图,只需更新最小值
}
v1[x].push_back({y, w});
}
memset(dis1, inf, sizeof dis1);
for(int i = 1; i <= n; i ++){
dij1(i);
}
for(int i = 1; i <= n; i ++){
int ans = inf;
for(int j = 1; j <= n; j ++){
if(i == j) continue;
ans = min(ans, dis1[i][j] + dis1[j][i]);//一个往返的时间
}
ans = min(ans, vis[i]); //最后跟自环的比大小
if(ans == inf) ans = -1;
printf("%d\n", ans);
}
}
int main(){
solve();
return 0;
}