2025牛客寒假算法基础集训营1

| A | 茕茕孑立之影 |
\(因为题目要求为互不为倍数\)
\(所以如果存在1的话必为-1\)
\(然后范围为1-1e9如果不存在1的话只需要找比1e9大的质数即可\)

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
void solve(){
    int n;cin>>n;
    int flag=0;
    for(int i=1;i<=n;i++){
        int x;cin>>x;
        if(x==1){
            flag=1;
        }
    }
    if(flag){
        cout<<-1<<'\n';return;
    }
    cout<<10000000019<<'\n';
}
signed main(){
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    cin >> _;
    while (_--) solve();
}

| B | 一气贯通之刃 | $只有为链时答案正确所以判一下链就行$
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
void solve(){
    int n;cin>>n;
    vector G(n+1,vector<int>());
    int now=0;
    for(int i=1;i<n;i++){
        int u,v;cin>>u>>v;
        G[u].pb(v);
        G[v].pb(u);
    }
    for(int i=1;i<=n;i++){
        if(G[i].size()==1) { now = i;break; }
    }
    int cnt=0,ans;
    function<void(int,int)>dfs=[&](int x,int fa){
        cnt++;
        int son=G[x][0];
        if(son==fa){
            if(G[x].size()==1) {ans=x; return; }
            else son=G[x][1];
        }
        dfs(son,x);
    };
    dfs(now,now);
    if(cnt==n){
        cout<<now<<" "<<ans<<"\n";
    }else cout<<-1;
}
signed main(){
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
//    cin >> _;
    while (_--) solve();
}

| C | 兢兢业业之移 | $通过BFS搜索到第一个向前状态转移即可$
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
const int N=2e5+10;
const int dx[4]{-1,0,1,0};
const int dy[4]{0,-1,0,1};
void solve(){
    int n;cin>>n;
    vector<string>g(n);
    for(int i=0;i<n;i++){
        cin>>g[i];
    }
    vector<vector<bool>>v(n,vector<bool>(n));
    vector<array<int,4>>ans;
    auto solve=[&](int sx,int sy){
        vector<vector<int>>d(n,vector<int>(n,-1));
        vector<vector<pair<int,int>>>pre(n,vector<pair<int,int>>(n));
        d[sx][sy]=0;
        queue<pair<int,int>>q;
        q.push({sx,sy});
        while(!q.empty()){
            auto [x,y]=q.front();
            q.pop();
            if(g[x][y]=='1'){
                while(x!=sx or y!=sy){
                    auto [nx,ny]=pre[x][y];
                    swap(g[x][y],g[nx][ny]);
                    ans.push_back({x,y,nx,ny});
                    x=nx,y=ny;
                }
                return;
            }
            for(int u=0;u<4;u++){
                int nx=x+dx[u];
                int ny=y+dy[u];
                if(nx<0 or nx>=n or ny <0 or ny>=n)continue;
                if(v[nx][ny] or d[nx][ny]!=-1)continue;
                d[nx][ny]=d[x][y]+1;
                pre[nx][ny]={x,y};
                q.push({nx,ny});
            }
        }
    };
    for(int i=0;i<n/2;i++){
        for(int j=0;j<n/2;j++){
            if(g[i][j]=='0'){
                solve(i,j);
            }
            v[i][j]=true;
        }
    }
    cout<<ans.size()<<'\n';
    for(auto [a,b,c,d]:ans){
        cout<<a+1<<" "<<b+1<<" "<<c+1<<" "<<d+1<<'\n';
    }
}
signed main(){
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    cin >> _;
    while (_--) solve();
}

| D | 双生双宿之决 | $用set去重map存储即可$
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
void solve(){
    map<int,int>mp;
    int n;cin>>n;
    set<int>s;
    for(int i=1;i<=n;i++){
        int x;cin>>x;
        s.insert(x);
        mp[x]++;
    }
    if(s.size()==2&&mp[*s.begin()]==mp[*s.rbegin()]){
        cout<<"Yes\n";
    }else cout<<"No\n";
}
signed main(){
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    cin >> _;
    while (_--) solve();
}

| E | 双生双宿之错 | $三分答案分上下两个区间求解$
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
const int N=2e5+10;
void solve(){
    int n;cin>>n;
    vector<int>a(n+1);
    for(int i=1;i<=n;i++)cin>>a[i];
    sort(all(a));
    auto get1=[&](int x){
        int cnt=0;
        for(int i=1;i<=n/2;i++){
            cnt+=abs(a[i]-x);
        }
        return cnt;
    };
    auto get2=[&](int x){
        int cnt=0;
        for(int i=n/2+1;i<=n;i++){
            cnt+=abs(a[i]-x);
        }
        return cnt;
    };
    int l1=1,r1=1e9;
    while(l1+2<r1){
        int mid1=l1+(r1-l1)/3;
        int mid2=r1-(r1-l1)/3;
        if(get1(mid1)<get1(mid2)){
            r1=mid2;
        }else l1=mid1;
    }
    int l2=1,r2=1e9;
    while(l2+2<r2){
        int mid1=l2+(r2-l2)/3;
        int mid2=r2-(r2-l2)/3;
        if(get2(mid1)<get2(mid2)){
            r2=mid2;
        }else l2=mid1;
    }
    int ans=1e18;
    for(int i=-5;i<=5;i++){
        for(int j=-5;j<=5;j++){
            if(l2+j==l1+i)continue;
            else ans=min(ans,get1(l1+i)+get2(l2+j));
        }
    }
    cout<<ans<<'\n';
}
signed main(){
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    cin >> _;
    while (_--) solve();
}


| H | 井然有序之窗 | $将区间以左端点排序后每次选择右端点尽量小的进行构造$
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
void solve(){
    int n;cin>>n;
    int sum=0;
    vector<int>a(n+1);
    for(int i=1;i<=n;i++)cin>>a[i],sum+=a[i];
    if(sum!=n*(n+1)/2){
        cout<<-1<<'\n';
    }else {
        sort(a.begin()+1,a.end());
        int big=0;
        int small=0;
        int cnt=0;
        for(int i=1;i<=n;i++){
            if(a[i]<i){
                int res=i-a[i];
                if(big>=res){
                    big-=res;
                }else {
                    cnt+=res-big;
                    big=0;
                }small+=res;
            }else {
                int res=a[i]-i;
                if(small>=res){
                    small-=res;

                }else {
                    cnt+=res-small;
                    small=0;
                }big+=res;
            }
        }
        cout<<cnt<<'\n';
    }
}
signed main(){
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
//    cin >> _;
    while (_--) solve();
}

| J | 硝基甲苯之袭 |
\(因为一个数的因数个数很少 所以通过枚举因数通过map进行动态增加即可\)

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
const int N=2e5+10;
vector<vector<int>>factor(N);
void init(){
    for (int i = 1; i <= N; ++i) {
        for (int j = i; j <= N; j += i) {
            factor[j].push_back(i);
        }
    }
}
void solve(){
    int n;cin>>n;
    vector<int>a(n+1);
    vector<int>vis(N*2,0);
    int cnt=0;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++){
        for(auto f:factor[a[i]]){
            int y=a[i]^f;
            if(vis[y]&&gcd(a[i],y)==f)cnt+=vis[y];
        }
        vis[a[i]]++;
//        cout<<cnt<<'\n';
    }
    cout<<cnt<<'\n';
}
signed main(){
    init();
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
//    cin >> _;
    while (_--) solve();
}

| M | 数值膨胀之美 | $如果有两个最小值那么答案必定为abs(max(mx,2*mi)-mi)$ $反之我们通过双指针对其动态转移即可$
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
void solve(){
    int n;cin>>n;
    map<int,int>mp,way;
    vector<int>a(n+1);
    multiset<int>s;
    int ans=1e18;
    function<void(int)>change=[&](int x){
        s.erase(s.find(x));
        s.insert(x*2);
        ans=min(ans,*s.rbegin()-*s.begin());
    };
    int mi=1e18,mx=-1e18;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        mp[a[i]]++;
        way[a[i]]=i;
        mi=min(mi,a[i]);
        mx=max(mx,a[i]);
        s.insert(a[i]);
    }
    {
        int pos=way[mi];
        int l=pos,r=pos;
        l--,r++;
        change(a[pos]);
        while((l!=0||r!=n+1))
        {
            while(l>=1&&a[l]*2<=mx){
                change(a[l]);
                l--;
            }
            while(r<=n&&a[r]*2<=mx){
                change(a[r]);
                r++;
            }
            if(l==0&&r==n+1)break;
            else if(l==0){
                mx=a[r]*2;
                change(a[r]);r++;
            }else if(r==n+1){
                mx=a[l]*2;
                change(a[l]),l--;
            }else {
                if(a[r]>a[l]){
                    mx=a[l]*2;
                    change(a[l]);
                    l--;
                }else {
                    mx=a[r]*2;
                    change(a[r]);
                    r++;
                }
            }
        }
        cout<<ans<<'\n';
    }
}
signed main(){
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
//    cin >> _;
    while (_--) solve();
}

posted @ 2025-01-24 13:34  archer2333  阅读(27)  评论(3)    收藏  举报