随笔 - 72,  文章 - 2,  评论 - 0,  阅读 - 1258

A. Sasha and Array Coloring

题意:加减号相同个数,问最大值是多少

思路:sort排序,双指针,加最大减最小,依次进行

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long

void  solve(){
    int n;
    cin>>n;
    vector<int>q(n);
    for (int i = 0; i < n; ++i) {
        cin>>q[i];
    }
    sort(q.begin(),q.end());
    int s=0;
    for (int l =0,r=n-1 ; l<r ; l++,r--) {
        s+=q[r]-q[l];
    }
    cout<<s<<endl;

}
signed main(){

    int t=1;
    cin>>t;
    while (t--){
        solve();
    }
}

B. Long Long

题意:有一个操作是将某个区间变成相反数,如何能使数组合最大,最大是多少,操作次数最小是多少

思路:0没有影响,把0去掉后,判断负正这样的相邻组合有几个,注意边界判断

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long

void  solve(){
    int n;
    cin>>n;
    vector<int >q;
    int s=0;
    for (int i = 0; i <n ; ++i) {
        int x;
        cin>>x;
        if(x!=0)q.push_back(x);
        s+= abs(x);
    }
    q.push_back(1);  int cnt=0;
    for (int i = 0; i <q.size() ; ++i) {
        if(q[i]<0&&q[i+1]>0)cnt++;
    }
    cout<<s<<' '<<cnt<<endl;

}
signed main(){

    int t=1;
    cin>>t;
    while (t--){
        solve();
    }
}

C. Sum in Binary Tree

题意:一个完全二叉树,求他父亲点的编号的和,包括自己

思路:二叉搜索,/2加即可

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long

void  solve(){
    int n;
    cin>>n;
    int s=0;
    while (n){
        s+=n;
        n/=2;
    }
    cout<<s<<endl;

}
signed main(){

    int t=1;
    cin>>t;
    while (t--){
        solve();
    }
}

D. Apple Tree

题意:一个树,每个叶子节点是一个苹果,问一个节点所对应的苹果和另一个节点所对应的苹果的组合数是多少

思路:本想BFS遍历一下记录节点的父亲,以及标记一下苹果,如何从苹果开始向上还原,父亲都加一,不过复杂度最差可能是n²,因此就爆。后来发现dfs回溯记录即可

代码:

正解(dfs)

#include<bits/stdc++.h>
using namespace std;
//#define int long long
vector<int>a[200005];
int ans[200006];
int dfs(int u,int f){
    if(a[u].size()==1&&a[u][0]==f){
        ans[u]=1;
        return 0;
    }
    for (auto i:a[u]) {
        if(i!=f){

            dfs(i,u);
            ans[u]=ans[u]+ans[i];
        }
    }
    return 0;

}
void  solve(){

    int n;
    cin>>n;
    for (int i = 0; i <= n; ++i) {
        a[i].clear();
        ans[i]=0;
    }

    for (int i = 1; i < n; ++i) {
        int x,y;
        cin>>x>>y;
        a[x].push_back(y);
        a[y].push_back(x);
    }
    dfs(1,-1);
    int m;
    cin>>m;
    for (int i = 0; i <m ; ++i) {
        int x,y;
        cin>>x>>y;
        cout<<(long long)ans[x]*ans[y]<<endl;
    }
}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);

    int t=1;
    cin>>t;
    while (t--){
        solve();
    }
}

tle(BFS):

#include<bits/stdc++.h>
using namespace std;
//#define int long long
vector<int>a[200005];
int fa[200006];
int ans[200006];
int vis[200006];
void  solve(){
    int n;
    cin>>n;
    for (int i = 0; i <= n; ++i) {
        a[i].clear();
        fa[i]=0;
        ans[i]=0;
        vis[i]=0;
    }

    for (int i = 1; i < n; ++i) {
        int x,y;
        cin>>x>>y;
        a[x].push_back(y);
        a[y].push_back(x);
    }
    int m;
    cin>>m;
    queue<int>q;
    q.push(1);
    fa[1]=1;
    vis[1]=1;
    vector<int>apple;
    while(!q.empty()){
        auto t=q.front();
        q.pop();
        if(a[t].size()==1&&t!=1){
            apple.push_back(t);
        }
        for (int i = 0; i <a[t].size() ; ++i) {
            int g=a[t][i];
            if(vis[g]==0){
                vis[g]=1;
                q.push(g);
                fa[g]=t;
            }
        }
    }
//    for (int i = 1; i <=n ; ++i) {
//        cout<<fa[i]<<' ';
//    }
        fa[1]=1;
    ans[1]=apple.size();
    for (int i=0;i<apple.size();i++) {
        for (int j = apple[i];j!=1 ; j=fa[j]) {
            ans[j]++;
        }
    }
//    for (int i = 1; i <=n ; ++i) {
//        cout<<ans[i]<<' ';
//    }
//    cout<<endl;

    while(m--){
        int x,y;
        cin>>x>>y;
        cout<<ans[x]*ans[y]<<endl;
    }
}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);

    int t=1;
    cin>>t;
    while (t--){
        solve();
    }
}

E. Tracking Segments

题意:一个操作,可以把一个数从0变成1,一共m个区间,n个点,q次操作,问第几次操作即可确定至少有一个区间的1的个数严格大于0的个数

思路:此题操作越多,条件就越容易成立,因此具有二分性,我们可以直接二分操作进行到第几次了,然后暴力,前缀求是否含有这种区间

代码:

#include<bits/stdc++.h>
using namespace std;
//#define int long long
#define  PII pair<int,int>
void  solve(){

    int n,m;
    cin>>n>>m;
    vector<PII>ve(m+1);

    for (int i = 1; i <=m; ++i) {
        cin>>ve[i].first>>ve[i].second;
    }
    int k;
    cin>>k;
    vector<int>q(k+1);

    for (int i = 1; i <=k ; ++i) {
        cin>>q[i];
    }
    int ans=0;
    int l=1,r=k;
    auto check = [&](int mid) ->bool {
            vector<int>sum(n+1);
            vector<int>g(n+1);
        for (int i = 1; i <=mid ; ++i) {
            g[q[i]]++;
        }
        for (int i = 1; i <=n ; ++i) {
            sum[i]=sum[i-1]+g[i];
        }
        int cnt=0;
        for (int i = 1; i <=m ; ++i) {
            cnt=sum[ve[i].second]-sum[ve[i].first-1];
            if(cnt> ( ve[i].second-ve[i].first+1) / 2)return true;
            //                int cnt = sum[ve[i].second] - sum[ve[i].first - 1];
//                if(cnt > (ve[i].second - ve[i].first + 1) / 2 )  return true;
        }
        return false;
    };

    while (l <= r)
    {
        int mid = l + r >> 1;
        if(check(mid)) {
            r = mid-1;
            ans=mid;
        }
        else   l = mid + 1;
    }
    if(check(ans))    cout << ans << "\n";
    else    cout << -1 << "\n";

}
int main(){

    int t=1;
    cin>>t;
    while (t--){
        solve();
    }
}
posted on   IR101  阅读(8)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示