Winter Training Three

F-Tokitsukaze and Eliminate (hard)_2024牛客寒假算法基础集训营2 (nowcoder.com)

题面:

思路:

  • 贪心求最优问题
  • 用两个map存储,一个mp存各个元素及其对应的个数,一个mp1存每轮遍历的元素和其个数
  • 从后往前遍历,如果mp1.size()刚好等于mp.size则满足一轮遍历(在遍历中要更新mp和mp1,并用erase删除mp遍历完的元素),如此从后向前遍历一轮即可
  • 最后再将余下的纯数一个个处理,所以直接加其个数即可

 (当时写的时候没写出来是因为我当时没想明白题目的意思,我不知道他是怎么去消除那些石头,我看了官方题解才明白题目的意思!!!说的到底还是我的思路出现了问题,还是需要多加练习练习去理解题目要求的)

AC代码:

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

const int N = 2e5+10;
int a[N];
void solve()
{
	int n;
	cin>>n;
	map<int,int> mp,mp1;
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		mp[a[i]]++;
	}
	int s=mp.size();
	for(int i=n;i>=1;i--)
	{
		mp[a[i]]--;
		mp1[a[i]]++;
		if(mp[a[i]]==0) mp.erase(a[i]);
		if(mp1.size()==s)
		{
			ans++;
			s=mp.size();
			mp1.clear();
		}
	}
	cout << ans <<endl;
}
signed main()
{
	ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	int T=1;
	cin>>T;
	while(T--) solve();
}

7-2 地下迷宫探索 - SMU 2024 winter round 3(补题) (pintia.cn)

题面:

题解:理解题意后发现就是一个dfs,由于深度优先遍历的节点序列是不唯一的,为了使得输出具有唯一的结果,我们约定以节点小编号优先的次序访问(点灯)。在点亮所有可以点亮的灯后,以原路返回的方式回到起点。

(我当时没写出来主要是卡在前面的一些题就没有看这题,

AC代码:

#include <iostream>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#include <stdio.h>
#include <string>

using namespace std;
int v[1005];
int b[1005][1005];
int n,m,s;
void dfs(int s)
{
    if(v[s]) return;
    v[s]=1;
    for(int i=1;i<=n;i++)
    {
        if(b[s][i]&&!v[i])
        {
            printf(" %d",i);
            dfs(i);
            printf(" %d",s);
        }
    }
}
int main()
{
    scanf("%d%d%d",&n,&m,&s);
    memset(v,0,sizeof(v));
    memset(b,0,sizeof(b));
    int x,y;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        b[x][y]=1;
        b[y][x]=1;
    }
    printf("%d",s);
    dfs(s);
    for(int i=1;i<=n;i++)
    {
        if(v[i]==0)
        {
            printf(" 0");
            break;
        }
    }
    printf("\n");
    return 0;
}

D-chino's bubble sort and maximum subarray sum(easy version)_2024牛客寒假算法基础集训营3 (nowcoder.com)

题面: 

思路:给出一段长度为N的数组,进行K次相邻元素的交换操作,求出最大子段和,数据给的比较小,且K=0或K=1,用前缀和处理然后暴力即可

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
const ll N=1e6+10;
ll n,m,k,t,sum,ans,flag;
ll cnt[N];
ll a[N];
string s,s1;
void slove(){
    cin>>n>>k;
    for(ll i=1;i<=n;i++) cin>>a[i];
    if(k==1){
        ans=-1e16;//a有<0的情况,取一个比较小的负值
        for(ll i=1;i<n;i++){
            swap(a[i],a[i+1]);//进行交换
            cnt[0]=0;//初始化
            for(ll i=1;i<=n;i++) cnt[i]=cnt[i-1]+a[i];//前缀和
            for(ll i=0;i<=n;i++){
                for(ll j=i+1;j<=n;j++)
                ans=max(ans,cnt[j]-cnt[i]);//cnt[j]-cnt[i]即i到j的子段和
            }
            swap(a[i],a[i+1]);//换回来,避免对后续产生影响
        }
        cout<<ans<<'\n';
    }
    else if(k==0){
        cnt[0]=0;
        for(ll i=1;i<=n;i++) cnt[i]=cnt[i-1]+a[i];
        for(ll i=0;i<=n;i++){
            for(ll j=i+1;j<=n;j++)
                ans=max(ans,cnt[j]-cnt[i]);
        }
        cout<<ans<<'\n';
    }
}
signed main(){
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    ll _ = 1;
    //cin >> _;
    while (_--) slove();
    return 0;
}

B-智乃的数字手串_2024牛客寒假算法基础集训营3 (nowcoder.com) 

思路:(博弈论

n=1时,必然是qcjj赢;(必胜态)

n=2时,无论是奇数还是偶数,qcjj必输;(必败态)

n=3时,qcjj可以取出一个数将其转换为n=2时的状态,这对zn来说必输;(必胜态)

n=4时,同样可以转换到n=3时的转态

总结得到n是奇数时,qcjj赢;n是偶数时,zn赢。

AC代码:

#include <bits/stdc++.h>
#include <iostream>
#define int long long
#define endl '\n'
using namespace std;
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t,n;
    cin>>t;
    while(t--)
    {
        cin>>n;
        int a[30];
        for(int i=1;i<=n;i++)
            cin>>a[i];
        if(n%2==0)cout<<"zn"<<endl;
        else cout<<"qcjj"<<endl;
    }
    return 0;
}

7-11 敲笨钟 - SMU 2024 winter round 3(补题) (pintia.cn)

题面:

 思路:按照题目的意思即可,我当时没写就是没想到使用string类的各种函数以及如何处理输入,

AC代码:

#include<bits/stdc++.h>
using namespace std;
int n;
char ch;
string s;
int main()
{
    cin>>n;
    while((ch=getchar())!='\n')continue;
    while(n--)
    {
        getline(cin,s);
        if(s.find("ong,")!=string::npos&&s.find("ong.")!=string::npos)
        {
            for(int k=1;k<=3;k++)
            {
                int t=s.rfind(" ");
                for(int i=t;s[i]!='\0';i++)s.erase(i--);
            }
            cout<<s<<" qiao ben zhong."<<endl;
        }
        else cout<<"Skipped"<<endl;
    }
    return 0;
}

(这周是有点偷懒了,补的题就没有那么多,现在年过完了,下周得好好收收心干我该干的事了) 

  • 23
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值