ABC305

A

思路:
比较100以内5的倍数与给定数的差值,绝对值最小的即为答案

B

题意:
给定一些点的位置,求给定两点的距离
思路:
开个map模拟即可

C

题意:
给定一个.矩阵,其中有一个由#构成的长方形
该长方形缺了一个点,即该处为.,求该点的位置
思路:
观察发现其他.上下左右至多只有一处和#接触,而题目要求的点至少有两处

D

题意:
给定一个位置数组,其中奇数下标到最右边靠近它的偶数下标的位置内,高桥是清醒的。
偶数下标到右边最靠近它的奇数下标的位置内,高桥是睡着的
q次询问,每次给定l和r,求这段区间内高桥睡着的总时间
思路:
我的代码是先统计清醒时间,然后用总时间减去得到答案
显然数据要求不能直接用数组差分模拟
不妨将分别考虑区间的主体部分和剩余部分
当区间左端点l落在清醒时间时,需要计算一下它占这一块的时间
右端点同理
中间的主体部分用数组前缀和即可
需要使用二分查找确定主体部分的左右端点

void solve(){
    int n;cin>>n;
    vector<int>a(n+1);
    rep(i,1,n)cin>>a[i];
    vector<int>pre(n+1);
    rep(i,1,n){
        if(i%2==0){
            pre[i]+=(a[i]-a[i-1]);
        }
        pre[i]+=pre[i-1];
    }

    int q;cin>>q;
    while(q--){
        int ans=0;
        int l,r;cin>>l>>r;
        int le,ri;
        int p=upper_bound(a.begin()+1,a.end(),l)-a.begin();
        le=p;
        p--;
        if((p&1)){
            ans+=(a[p+1]-l);
        }
        p=upper_bound(a.begin()+1,a.end(),r)-a.begin();
        p--;
        ri=p;
        if(p&1){
            ans+=(r-a[p]);
        }
        ans+=pre[ri]-pre[le];

        cout<<(r-l)-ans<<endl;
    }
}

E

题意:
给定一个无向图,其中k个点分别有权值a[i]
当图上某个点的与这k个点的任意一个点的距离小于等于其权值时,说它是被守卫的
输出有多少个点是被守卫的
思路:
看起来像是以这k个点为中心向外扩散
不妨设每个点的权值如果大于等于0,则是被守卫的
以Dijkstra的思想来看,每次取图中权值最大的,用来更新其他点
那么最后每个点的权值一定是能获得的最大的

int n,m,k;
vector<int>e[maxn];
void solve(){
    cin>>n>>m>>k;
    vector<int>d(n+1);
    rep(i,1,n){
        d[i]=-1;
    }
    rep(i,1,m){
        int u,v;cin>>u>>v;
        e[u].pb(v);e[v].pb(u);
    }
    priority_queue<pii>q;
    rep(i,1,k){
        int p,h;cin>>p>>h;
        d[p]=h;
        q.push({h,p});
    }
    vector<int>vis(n+1);
    while(q.size()){
        auto[x,y]=q.top();q.pop();
        if(vis[y])continue;
        vis[y]=1;

        for(int v:e[y]){
            if(d[v]<x-1){
                d[v]=x-1;
                q.push({d[v],v});
            }
        }
    }
    vector<int>ans;
    rep(i,1,n){
        if(d[i]>=0){
            ans.pb(i);
        }
    }

    cout<<ans.size()<<endl;
    for(int i=0;i<ans.size();i++){
        cout<<ans[i]<<' ';
    }
    cout<<endl;
}

F

题意:
交互题,无向图,图开始是未知的。从1开始,每次到达一个点告诉你其连接的点,要求你通过输出到达n
思路:
注意,交互题需要关ios,需要cout<<flush,每次输入都要写进代码里,输出到答案时exit0立即退出程序
DFS即可,每个点访问最多两次

vector<int>e[500];
int vis[500];
int n,m;
void dfs(int u){
    if(u==n)exit(0);
    vis[u]=1;
    int k;cin>>k;
    for(int i=1;i<=k;i++){
        int v;cin>>v;
        e[u].pb(v);
    }
    for(int v:e[u]){
        if(!vis[v]){
            cout<<v<<endl;cout<<flush;
            dfs(v);
        cout<<u<<endl;
        cout<<flush;
        cin>>k;
        for(int i=1;i<=k;i++){
            int _;
            cin>>_;
        }
        }
    }
}
void solve(){
    cin>>n>>m;
    int u=1;
    dfs(u);
}
posted @ 2025-06-05 15:20  Marinaco  阅读(6)  评论(0)    收藏  举报
//雪花飘落效果