AtCoder Beginner Contest 191 解题报告

题目链接:点这里~

比赛心得:遇到几何不要慌,试试看暴力行不行=。 =

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;
}

 

猜你喜欢

转载自blog.csdn.net/weixin_43911947/article/details/113732144
今日推荐