AtCoder Beginner Contest 191 Problem Solving Report

Topic link: click here~

Game experience: Don’t panic when you encounter geometry, try to see if violence works=. =

A - Vanishing Pitch

Topic

v represents the ball speed, ts represents a time interval, d represents the distance of the ball from the baseball player

The ball flies at a constant speed and disappears in the time interval [t,s]. Ask the baseball player if he can hit the baseball in the end

Ideas

Find the time d/v it takes for the ball to fly to the baseball player, and see if it’s within that time period.

If you are afraid of accuracy problems, you can turn the time interval into a distance interval [vt, vs], and then see if d is within the interval.

ac code

#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 

Topic

Give you a sequence of length n and another m, and then ask you to remove all the numbers equal to m in the sequence and output the remaining numbers

Ideas

Judge whether to keep, save directly with vector

ac code

#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

Topic

Give you a center coordinate and radius, and ask you how many whole points the circle contains

Ideas

Although it is a geometric problem that is not good at it, it’s okay to violently run the abscissa of the whole point, then find the two vertical coordinates, and then sum the whole points between the upper and lower coordinates, but the accuracy will be lost, so here The response method is radius R+1e-14

ac code

#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

Topic

There are m roads in n cities, and each road ai, bi, ci represents a single road from ai to bi. It takes ci minutes to walk, and there may be heavy edges and self-loops. Is it possible to start from the i-th city and then return to that city to form a ring? The shortest time can be output, otherwise -1

Ideas

Time is given for 3s, 2000 points, directly considering n priority queue optimization dijkstra, find the shortest route from city i to other cities, and a for updates the minimum value of running back and forth. Finally, see if there is a self-loop, if there is the shortest time for the self-loop, then take the smaller one from the previously updated minimum.

ac code

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

 

Guess you like

Origin blog.csdn.net/weixin_43911947/article/details/113732144
Recommended