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

文章讲述了Tokitsukaze参与的不同编程题目,涉及数组操作、模拟、消除游戏和动态规划等技巧。每个问题都有相应的解题思路和代码示例,展示了在不同难度级别下的解决方案。
摘要由CSDN通过智能技术生成

这场cf味太太太太重了

A Tokitsukaze and Bracelet

签到

题干:

题解:

看懂题干就能写

void solve(){
    int a,b,c;
    cin>>a>>b>>c;
    int ans=0;
   if(a==150) ans+=1;
    else if(a==200) ans+=2;
    if(b>32 and b<41) ans+=1;
    else if(b>42) ans+=2;
     if(c>32 and c<41) ans+=1;
    else if(c>42) ans+=2;
    cout<<ans<<endl;
}

B Tokitsukaze and Cats

签到

题干:

题解:

根据题意模拟即可

int a[305][305]={0};
void solve(){
       int n,m,k;
    cin>>n>>m>>k;
    while(k--){
        int x,y;
        cin>>x>>y;
       a[x][y]=1;
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(!a[i][j])continue;
            if(j>1 and a[i][j-1]) ans++;
            else if(j>1 and !a[i][j-1])ans+=2;
            else if(j==1)ans+=2;
            if(i>1 and a[i-1][j]) ans++;
                else if(i>1 and !a[i-1][j]) ans+=2;
            
            else if(i==1)ans+=2;
        }
    }
    cout<<ans;
}

C  Tokitsukaze and Eliminate (easy)

题干:

Tokitsukaze 正在玩一个消除游戏。

初始有 nnn 个宝石从左到右排成一排,第 iii 个宝石的颜色为 colicol_icoli​。Tokitsukaze 可以进行若干次以下操作:

  •  任选一种颜色 xxx,将颜色为 xxx 的最右边那颗宝石、以及该宝石右边的所有宝石全部消除。

Tokitsukaze 想知道至少需要几次操作才能把 nnn 个宝石全部消除。

题解:

由于宝石的颜色只有两种,因此只要每次选择和末尾宝石颜色不同的宝石即可,如果只剩一类宝石了那么只能一个一个删,从后往前模拟即可

void solve(){
    unordered_map<int,int>mp1,mp2;
    int n;
    cin>>n;
    vector<int>a(n);
    for(int i=0;i<n;i++){
        cin>>a[i];
        mp1[a[i]]++;
    }
    int cnt=0,tmp=0,pos=n-1;
    for(int i=n-1;i>=0;i--){
        if(!mp2[a[i]]) mp2[a[i]]++,tmp++;
        if(tmp==mp1.size()){
            for(int j=i;j<=pos;j++){
                mp1[a[j]]--;
                if(mp1[a[j]]==0) mp1.erase(a[j]);
            }
            mp2.clear();
            cnt++;
            pos=i-1;
            tmp=0;
        }
    }
    cout<<cnt<<endl;
}

I Tokitsukaze and Short Path (plus)

题干:

纯纯诈骗题,看见数据范围就知道不能是建图,列一张表出来就能找到规律了。将序列升序排序后进行n-1次操作,每次操作sum加上max(a[i],a[i+1])*k即可,k是4,8,12……。

void solve(){
   int n;
   cin>>n;
   vector<int>a(n);
   for(int i=0;i<n;i++) cin>>a[i];
   sort(a.begin(),a.end());
   int k=4;
   int sum=0;
   for(int i=0;i<n-1;i++){
    sum+=max(a[i],a[i+1])*k;
    k+=4;
   }  
   cout<<sum<<endl;
}

J Tokitsukaze and Short Path (minus)

题干:

题解:

和上面一样,就是把边权公式换了,列个表就能发现如下规律:

升序排序后:

1. 第一个点与其他点的路径长度为2*a[0]

2. 其他的点与不为1的点之间的路径分为两种: 

(1)如果两者间的路径2*min(a[i],a[i+1]) 比4*a[i]小,那就取前者

(2)反之取4*a[i],就是从两个点经过1这个中转点。

void solve(){
   int n;
   cin>>n;
   vector<int>a(n);
   for(int i=0;i<n;i++) cin>>a[i];
   sort(a.begin(),a.end());
   int sum=0;
   int k=2*(n-1);
   for(int i=0;i<n-1;i++){
    if(i==0) sum+=k*a[i]*2;
    else{
        if(min(a[i],a[i+1])>=2*a[0]) sum+=k*a[0]*4;
        else sum+=k*min(a[i],a[i+1])*2;
    }
    k-=2;
   }  
   cout<<sum<<endl;
}

D Tokitsukaze and Slash Draw

题干:

题解:

推出状态疯狂调dp,dp不是一种好算法,直接看代码

#include<bits/stdc++.h>
using namespace std;
#define int long long 
const int N =1e6+10;
const int INF=0x3f3f3f3f;
typedef pair<int, int> pII;
#define x first
#define y second
typedef long long ll;
#define pb push_back
#define P push
const int mod=1e9+7;
#define endl '\n'
const double eps=1e-5;
int ddx[]={1,1,0,-1};
int ddy[]={0,1,1,1};
int dp[N];
const int inf=1e18;
void solve(){
    int n,m,k;
    cin>>n>>m>>k;
    for(int i=0;i<n;i++) dp[i]=inf;
    dp[k-1]=0;
    queue<pII>t;
    vector<int>a(n+1),b(n+1);
    for(int i=1;i<=m;i++) cin>>a[i]>>b[i];
    for(int i=1;i<=m;i++){
        for(int j=0;j<n;j++){
         if(dp[j]==inf) continue; 
         t.P({j,dp[j]}); 
        }
       while(t.size()!=0){
            int tmp1=t.front().x,tmp2=t.front().y;
            t.pop();
              if(dp[(tmp1+a[i]+n)%n]>tmp2+b[i]){
                    dp[(tmp1+a[i]+n)%n]=b[i]+tmp2;
                    t.P({(tmp1+a[i]+n)%n,dp[(tmp1+a[i])%n]});
                }
        }
    }
    if(dp[n-1]==inf) cout<<-1<<endl;
    else cout<<dp[n-1]<<endl;
}
signed main(){
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    int T= 1;
    cin>>T;
   for(int i=1;i<=T;i++){
      solve();
   }
    return 0;
}

F Tokitsukaze and Eliminate (hard)

题干:

和E的区别就在于E只有两个颜色,而这题有n个

void solve(){
        int n;
        cin>>n;
        vector<int>a(n+1);
        map<int,int>mp1,mp2;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            mp1[a[i]]++;
        }
        int pos=mp1.size();
                int ans=0;
        for(int i=n;i>=1;i--){
            if(mp1.size()==1){
                ans+=i;
                break;
            }
            mp2[a[i]]++;
            mp1[a[i]]--;
            if(mp1[a[i]]==0) mp1.erase(a[i]);
            if(mp2.size()==pos){
                ans++;
                mp2.clear();
                pos=mp1.size();
            }
        }
        cout<<ans<<endl;
}

其他的先不补了

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值