2022/7/10/2022河南萌新新联赛第一场:河南工业大学比赛题解[2022河南萌新联赛第(一)场:河南工业大学_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (n

A题:A-Alice and Bob_2022河南萌新联赛第(一)场:河南工业大学 (nowcoder.com)

关键词:质因数分解(以质数分堆),博弈论(尼姆游戏),异或运算

Alice赢的情况:1.每一堆都为1,且为偶数堆;2.存在一堆不为1,且是奇数堆

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
int main()
{
	ll n,c=0,ans=0;
	cin>>n;
	for(ll i=2;i*i<=n;i++)
	{
		if(n%i==0)
		{
			ll cnt=0;//临时标记这一堆有多少石子
			while(n%i==0)
				n/=i,cnt++;
			if(cnt>1)//超过1就标记
				c=1;
			ans^=cnt;//计算堆值,判断奇偶
		}
	}
	if(n>1)ans^=1;//n为质数
	if((ans==0&&c==0)||(ans>0&&c==1))
		puts("Alice win");
	else puts("Bob win");
}

B题:B-打对子_2022河南萌新联赛第(一)场:河南工业大学 (nowcoder.com)

利用异或运算判断每个字符出现的次数为奇数次还是偶次,剩余的牌的数量==出现奇数次字符的和.

#include<bits/stdc++.h>
using namespace std;
int x[26],y[26];//存26个字母,0为偶次,1为奇数次
int main()
{
	int n;
	string a,b;
	cin>>n>>a>>b;
	for(int i=0;i<n;i++)
	{
		x[a[i]-'A']^=1;
		y[b[i]-'A']^=1;
	}
	int c=0,d=0;
	for(int i=0;i<26;i++)
	{
		c+=x[i];
		d+=y[i];
	}
	if(c<d){cout<<c<<endl;puts("YES");}
	else cout<<c<<endl,puts("NO");
}

C题:C-割竿榄_2022河南萌新联赛第(一)场:河南工业大学 (nowcoder.com)

关键词:数据范围long long,前缀和,

解决本题需要分三种情况:1,不能割遍整个田野的情况;2,能割遍且无重叠的情况;3,能割遍有重叠的情况。

针对第二种情况,首先把原有全部的竿揽总和到答案中,然后计算(除最后一遍割遍田野的次数)的生长值加入答案,最后再把最后一遍的生长值加入(此时会割光为0);

针对第一种情况,利用前缀和,计算能割到范围的最大值,最后再加上生长值。

#include<bits/stdc++.h>
using namespace std;
int b[200005];
long long s[200005];//注意防int爆炸
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>b[i];
		s[i]=s[i-1]+b[i];//前缀和
	}
	long long ans=0;
	if(3*m>n)//能割遍的情况
	{
		if(n%3==0)//能刚好割遍
		{
			ans=s[n];
			ans+=1ll*(m-n/3)*n;
			for(int i=0;i<n/3;i++)
				ans+=i*3;//最后一次割遍
		}
		else //有重叠
		{
			ans=s[n]-1;
			//有一个不能割为0(非重叠部分)或者有一个割为0后不生长(重叠部分)
			ans+=1ll*(m-(n+2)/3)*n;//(n+2)/3为最后一次割所需要的次数
			for(int i=0;i<(n+2)/3;i++)
				ans+=i*3;
		}
	}
	else //不能割遍
	{
		for(int i=1,j=3*m;j<=n;i++,j++)
			ans=max(ans,(s[j]-s[i-1]));
		for(int i=0;i<m;i++)
			ans+=i*3;
	}
	cout<<ans<<endl;
}

D题:D-纪念品领取_2022河南萌新联赛第(一)场:河南工业大学 (nowcoder.com)

利用结构体,分别对每个人的编号,排队位置赋初值,按题意操作后,对其进行两次排序,一次为确定前五的位置,另一次为为前五按编号递增序号排序,最后按顺序输出就好啦。

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

struct node
{
   int c,num; 
}t[200005];

bool cmp(node x,node y)
{
    return x.num<y.num;
}

bool cmp1(node x,node y)
{
    return x.c<y.c;
}

int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        t[i].c=i;
        t[i].num=i;
    }
    int j=n;
    for(int i=1;i<=m;i++)
    {
        int x;
        cin>>x;
        t[x].num=++j;
    }
    sort(t+1,t+1+n,cmp);   
    sort(t+1,t+5+1,cmp1);//对前5排序
    for(int i=1;i<=5;i++)
        cout<<t[i].c<<" ";
}

E题:https://ac.nowcoder.com/acm/contest/37160/E
本题要点:1、排序;2、利用res来检查需要出现的值

#include<bits/stdc++.h>
using namespace std;
long long b[200005];
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>b[i];
    sort(b,b+n);
    long long res=1;
    for(int i=0;i<n;i++)
    {
        if(res<b[i]){cout<<res;return 0;}//当需出现的值未出现,此时res为结果
        else if(res>=b[i])
        {
            res+=b[i];//全集和的下一个数
        }
    }
    cout<<res;
    return 0;  
}

F题:https://ac.nowcoder.com/acm/contest/37160/F
贪心,从最远可达点去选择最靠前的买车地。

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int a,b,c;
}t[200005];

bool cmp(node x,node y)
{
    return x.c<y.c;
}

int main()
{
    int n,m,k;
    cin>>n>>m>>k;
    t[0].a=0,t[0].b=k,t[0].c=k;
    for(int i=1;i<=m;i++)
    {
        cin>>t[i].a>>t[i].b;
        t[i].c=t[i].a+t[i].b;
    }
    sort(t,t+m+1,cmp);
    int res=n,cnt=0;
    while(res)
    {
        int p=0;
        int temp=INT_MAX;
        for(int i=0;i<m+1;i++)
           if(t[i].c>=res&&t[i].a<res)
               if(temp>t[i].a)temp=t[i].a,p=1;
        if(p==0){puts("-1");return 0;}
       res=temp,cnt++;    
    }
    cout<<cnt-1;
}

K题:K-糟糕的一天_2022河南萌新联赛第(一)场:河南工业大学 (nowcoder.com)

签到题,看后面有没有比它大的数就行

#include<bits/stdc++.h>
using namespace std;
int b[1000005];
int main()
{
    int n,ans=0;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>b[i];
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            if(b[i]<b[j])
            {
                ans++;break;
            }
        }
    }
    cout<<ans<<endl;
}

欠四题,完。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
USACO2022金组是国际在线判题系统USACO的最高级别,题目难度较高,在该比赛中取得好成绩是一项巨大的成就。以下是对该比赛的一些题目解析。 第一题:“交通计划” 题目要求:给定一个n个节点的有向图,每条边有一个长度,希望添加最少的边使得所有节点连通,求最小生成树的权值和。 解析:该题可以使用Kruskal算法求解,将每条边按权值从小到大排序,再依次加入,判断加入的边是否会形成环,若形成则不加入,直到所有节点连通为止。此时Kruskal算法得到的最小生成树的权值和即为所求。 第二题:“点火计划” 题目要求:给定一个n个节点的有向图,每条边有一个权值和一个点火时长,每个节点有一个点火启动时刻和时刻结束时刻,希望从其中选出一些边点火,使得所有节点都可从点火的边出发到达,且所选点火边的总点火时长最小。 解析:该题可以使用最小费用最大流算法求解。将每条边看做一个容量为1,费用为点火时长的边,源点向节点的点火边容量为1,费用为0的边,节点的点火边向汇点的容量为1,费用为0的边,对这个网络进行最小费用最大流即可得到所选边的总点火时长最小。 第三题:“美味佳肴” 题目要求:给定n个菜品,每个菜品有它的权值和两个类别,希望选出k个菜品,使得选出的菜品数量在每个类别中都不超过$\frac{k}{3}$个,且所选菜品的权值和最大。 解析:该题可以使用动态规划求解。设$f[i][j][k]$表示前i个菜品中,选择j个一类菜品,选择k个二类菜品的最大权值和,状态转移方程为$f[i][j][k]=max(f[i-1][j][k],f[i-1][j-1][k]+a[i],f[i-1][j][k-1]+b[i])$,其中a[i]为i号菜品的权值,若为一类则为该权值,否则为0,b[i]为i号菜品的权值,若为二类则为该权值,否则为0。最终答案为$f[n][$k/3$][$k/3$]。 以上是对USACO2022金组的部分题目的解析,USACO比赛是全球范围内的计算机竞赛,竞争非常激烈,能够在该比赛中脱颖而出是一项非常棒的成就。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值