2024牛客寒假算法基础集训营5

A.

总数-1的个数

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

#define int long long
const int N=1e5+10;
#define inf 0x3f3f3f3f

void solve() {
    int n;cin>>n;
    int ans=0;
    for(int i=1,x;i<=n;i++){
        cin>>x;
        if(x==1)continue;
        ans++;
    }
    cout<<ans;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int left=1;
    //cin>>left;
    while(left--){
        solve();
    }
}

B.

第一个数能放的都放在前面,然后后面的数取相邻间最小的
最后一个数最后也可以放

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

#define int long long
const int N=1e5+10;
#define inf 0x3f3f3f3f

void solve() {
    int n;cin>>n;
    vector<int>a(n+2);
    for(int i=1;i<=n;i++)cin>>a[i];
    a[0]=inf;a[n+1]=inf;
    int last=inf;
    int ans=0;
    for(int i=1;i<=n;i++){
        if(last>=a[i]){
            ans+=a[i]-1;
            last=0;
        }else{
            ans+=last;
            last=a[i]-last-1;
        }
    }
    if(last)ans+=last;
    cout<<ans;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int left=1;
    //cin>>left;
    while(left--){
        solve();
    }
}

G.

n方去枚举每个数与哪些数可以满足条件,然后二分图跑

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

#define int long long
const int N=2e6+10;
#define inf 0x3f3f3f3f

bool is_prime[N];//是否是质数,0为是,1为不是
int prime[N];//质数数组
int top=1;//质数的下标
int min_p[N];//最小质因数数组
void get_prime(int n){
    for(int i=2;i<=n;i++){
        if(!is_prime[i]){//是质数
            prime[top]=i;//存质数
            min_p[i]=i;//质数的最小质因数是本身
            top++;//下标后移
        }
        for(int j=1;j<top;j++){//最小到达遍历质数数组
            if(i*prime[j]>n)break;
            is_prime[i*prime[j]]=1;//标记质数的倍数即合数
            min_p[i*prime[j]]=prime[j];//质数的倍数的最小质因数是该质数
            if(i%prime[j]==0)break;//若i是之前质数的倍数,说明这个倍数会在后面的循环内被筛去,无需继续循环
        }
    }
}
vector<int>l[N/2];//边信息
int boy[N/2];//匹配信息
int used[N/2];//标记数组
int k,m;//配对信息,m点集,n点集
bool find(int i){
    for(int j=0;j<l[i].size();j++){
        if(!used[l[i][j]]){
            used[l[i][j]]=1;
            if(!boy[l[i][j]]||find(boy[l[i][j]])){
                boy[l[i][j]]=i;
                return true;
            }
        }
    }
    return false;
}
void solve() {
    int n;cin>>n;
    get_prime(2*n+10);
    //vector<int>ans(n+1);//vis(n+1,0);
    //int cnt=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            // if(vis[j])continue;
            if(is_prime[i+j]==0){
                l[i].push_back(j);
            }
        }
    }
    memset(boy,0,sizeof(boy));
    int sum=0;
    for(int i=1;i<=n;i++){
        memset(used,0,sizeof(used));
        if(find(i))sum++;
    }
    if(sum>=n){
        for(int i=1;i<=n;i++)cout<<boy[i]<<' ';
        cout<<'\n';
    }else cout<<"-1\n";
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int left=1;
    //cin>>left;
    while(left--){
        solve();
    }
}

H.

1-n的顺序序列,相差为1
让n从1开始遍历到谁能够得到质数
比如n+3是质数,那么n-1和4也一定是质数
这样两两配对后若还有1个数,则把这个数和与n配对的那个数之前的那些数暴力二分图

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

#define int long long
const int N=2e6+10;
#define inf 0x3f3f3f3f

bool is_prime[N];//是否是质数,0为是,1为不是
int prime[N];//质数数组
int top=1;//质数的下标
int min_p[N];//最小质因数数组
void get_prime(int n){
    for(int i=2;i<=n;i++){
        if(!is_prime[i]){//是质数
            prime[top]=i;//存质数
            min_p[i]=i;//质数的最小质因数是本身
            top++;//下标后移
        }
        for(int j=1;j<top;j++){//最小到达遍历质数数组
            if(i*prime[j]>n)break;
            is_prime[i*prime[j]]=1;//标记质数的倍数即合数
            min_p[i*prime[j]]=prime[j];//质数的倍数的最小质因数是该质数
            if(i%prime[j]==0)break;//若i是之前质数的倍数,说明这个倍数会在后面的循环内被筛去,无需继续循环
        }
    }
}
vector<int>l[N/2];//边信息
int boy[N/2];//匹配信息
int used[N/2];//标记数组
int k,m;//配对信息,m点集,n点集
bool find(int i){
    for(int j=0;j<l[i].size();j++){
        if(!used[l[i][j]]){
            used[l[i][j]]=1;
            if(!boy[l[i][j]]||find(boy[l[i][j]])){
                boy[l[i][j]]=i;
                return true;
            }
        }
    }
    return false;
}
void solve() {
    int n;cin>>n;
    get_prime(2*n+10);
    //vector<int>ans(n+1);//vis(n+1,0);
    //int cnt=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            // if(vis[j])continue;
            if(is_prime[i+j]==0){
                l[i].push_back(j);
            }
        }
    }
    memset(boy,0,sizeof(boy));
    int sum=0;
    for(int i=1;i<=n;i++){
        memset(used,0,sizeof(used));
        if(find(i))sum++;
    }
    if(sum>=n){
        for(int i=1;i<=n;i++)cout<<boy[i]<<' ';
        cout<<'\n';
    }else cout<<"-1\n";
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int left=1;
    //cin>>left;
    while(left--){
        solve();
    }
}

I.

模拟

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

#define int long long
const int N=1e5+10;
#define inf 0x3f3f3f3f

void solve() {
    int t,a,k;cin>>t>>a>>k;
    if(t==0){
        cout<<abs(a);
        return ;
    }
    if(a==0){
        cout<<abs(t);
        return ;
    }
    if(t>0&&a>0){
        if(t>=a){
            cout<<t;
        }else {
            cout<<(a+(a-t));
        }
        return ;
    }
    if(t<0&&a<0){
        t=-t;a=-a;
        if(t>=a){
            cout<<t;
        }else {
            cout<<(a+(a-t));
        }
        return ;
    }
    if(abs(a)<=k){
        cout<<(2*abs(a)+abs(t));
    }else{
        cout<<(3*abs(t)+2*abs(a));
    }
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int left=1;
    //cin>>left;
    while(left--){
        solve();
    }
}

M.

考虑如何分割
要么竖着切割,要么错位1个分割
两种方法都跑,能1次解决就一次,最多两次
特判n=1和2

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

#define int long long
const int N=1e5+10;
#define inf 0x3f3f3f3f

void solve() {
    int n;cin>>n;
    vector<int>a(n+1),b(n+1);
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++)cin>>b[i];
    if(n==1){
        cout<<"-1\n";return ;
    }
    if(n==2){
        if(a[1]==b[1]) {
            cout << "-1\n";
            return;
        }
        cout<<"1\n";return ;
    }
    for(int i=2;i<=n-1;i++){
        if(a[i]==b[i]){
            cout<<"1\n";return ;
        }
    }
    for(int i=1;i<n;i++){
        if(a[i]==b[i+1]||b[i]==a[i+1]){
            cout<<"1\n";return ;
        }
    }
    cout<<"2\n";
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int left=1;
    cin>>left;
    while(left--){
        solve();
    }
}

posted @ 2024-02-21 20:38  WW爆米花  阅读(30)  评论(0编辑  收藏  举报