河南萌新联赛2024第(一)场(部分题解)

目录

 

A.造数

B.爱探险的朵拉

C.有大家喜欢的零食吗 

F.两难抉择新编

G.旅途的终点

H.两难抉择

I.除法移位

K.图上计数(Easy)


 

A.造数

​​​​​​aA-造数_河南萌新联赛2024第(一)场:河南农业大学 (nowcoder.com)

倒过来思考,看最少几部可以将n变成0。

但有些部分需要贪心,当n为1和2时需要一步就可以完成,大于这个数分奇数偶数讨论,偶数给他除以2,奇数就直接使它变成偶数。

#include<bits/stdc++.h>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 2e14 + 10;
const int mod = 1e9 + 7;
inline void solve() {
	int n;
	cin >> n;
	int ans = 0;
	while (n) {
		if(n==1||n==2)
		{
			ans++;
			break;
		}
		else if(n%2==0)
		{
			ans++;
			n/=2;
		}
		else
		{
			n--;
			ans++;
		}
	}
	cout<<ans<<"\n";
}
signed main() {
	solve();
	return 0;
}

B.爱探险的朵拉

B-爱探险的朵拉_河南萌新联赛2024第(一)场:河南农业大学 (nowcoder.com)

因为我们需要从每个点为起点开始遍历,我们可以用dfs查找最大答案。

但是单纯的dfs只能过百分之90的数据,所以我们这里需要记忆化搜索,用一个dp数组记录下值,这样可以减少重复遍历的时间。

#include<bits/stdc++.h>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 2e14 + 10;
const int mod = 1e9 + 7;
int n,a[N],v[N],sum=0,ans=0,dp[N];
int dfs(int i)
{
	v[i]=1;
	if(v[a[i]]==0) dp[i]=dfs(a[i])+1;
	else dp[i]=1;
	v[i]=0;
	return dp[i];
}
inline void solve() {
	
	cin>>n;
	
	for(int i=1;i<=n;i++) cin>>a[i];
	
	for(int i=1;i<=n;i++)
	{
		sum=0;
		if(dp[i]==0) dfs(i);
		ans=max(dp[i],ans);
		if(ans==n) break;
	}
	cout<<ans<<"\n";
}
signed main() {
	solve();
	return 0;
}

C.有大家喜欢的零食吗 

C-有大家喜欢的零食吗_河南萌新联赛2024第(一)场:河南农业大学 (nowcoder.com)

一开始没反应过来,后来发现就是一个二部图的最大匹配问题,需要用到匈牙利算法。

#include<bits/stdc++.h>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 2e14 + 10;
const int mod = 1e9 + 7;
vector<vector<int> >mp;
int n;
int match[N],v[N];
bool dfs(int x,int tag)
{
	if(v[x]==tag) return false;
	v[x]=tag;
	for(auto k:mp[x])
	{
		if(!match[k]||dfs(match[k],tag))
		{
			match[k]=x;
			return true;
		}
	}
	return false;
	
}
inline void solve() {
	
	cin>>n;
	mp.resize(n+1);
	for(int i=1;i<=n;i++)
	{
		int k;
		cin>>k;
		for(int j=1;j<=k;j++)
		{
			int p;
			cin>>p;
			mp[i].push_back(p);
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		if(dfs(i,i)) ans++;
	}
	if(n-ans==0)
	{
		cout<<"Yes\n";
	}
	else
	{
		cout<<"No\n";
		cout<<n-ans<<"\n";
	}
	
}
signed main() {
	solve();
	return 0;
}

F.两难抉择新编

F-两难抉择新编_河南萌新联赛2024第(一)场:河南农业大学 (nowcoder.com)

我们先用一个变量ans记录所有元素的异或和。

因为可以取的是1到n/i,所以我们可以暴力求解,我们改变某一个数,那就用ans异或这个数,相当于将它去除ans,再异或改变后的数,那就完成了改变,用一个变量更新最大值。

#include<bits/stdc++.h>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 2e14 + 10;
const int mod = 1e9 + 7;
inline void solve() {
	int n;
	cin >> n;
	int oo = 0;
	vector<int>a(n + 1);
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		oo ^= a[i];
	}
	int ans = oo;
	for (int i = 1; i <= n; i++) {
		for(int j=1;j<=n/i;j++){
			
			int l=a[i]+j;
			int r=a[i]*j; 
			ans=max(ans,oo^a[i]^l);
			ans=max(ans,oo^a[i]^r);
		}
	}
	cout<<ans<<"\n";
}
signed main() {
	solve();
	return 0;
}

G.旅途的终点

G-旅途的终点_河南萌新联赛2024第(一)场:河南农业大学 (nowcoder.com)

一开始没有看清楚题目,我以为是挑选城市去旅游,我就直接排序贪心,结果wa了。

后来才发现必须从1到n,所以需要使用一个优先队列去维护我们的最大值,当当前我们的体力不能支撑时,我们反悔之前使用的最大体力(前提是有神力次数,不然就直接输出当前遍历的位置-1)。

#include<bits/stdc++.h>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 2e14 + 10;
const int mod = 1e9 + 7;
inline void solve() {
	int n,c,k;
	cin>>n>>c>>k;
	vector<int>a(n+1);
	priority_queue<int>q;
	for(int i=1;i<=n;i++) cin>>a[i];
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		c-=a[i];
		q.push(a[i]);
		if(c<=0)
		{
			if(k==0)
			{
				cout<<i-1<<"\n";
				return;
			}
			c+=q.top();
			k--;
			q.pop();
		}
	}
	cout<<n<<"\n";
	
}
signed main() {
	solve();
	return 0;
}

H.两难抉择

H-两难抉择_河南萌新联赛2024第(一)场:河南农业大学 (nowcoder.com)

我们可以贪心一下。

发现当x或者ai为1时,相乘不如相加,反之相乘一直都是最优的。

#include<bits/stdc++.h>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 2e14 + 10;
const int mod = 1e9 + 7;

inline void solve() {
	int n;
	cin>>n;
	int mx=-1,mi=1e9,sum=0;
	for(int i=1,x;i<=n;i++)
	{
		cin>>x;
		sum+=x;
		mx=max(mx,x);
		mi=min(mi,x);	
	}
	if(n==1||mx==1)
	{
		cout<<sum+n<<"\n";
		return;
	}
	cout<<(sum-mx)+mx*n<<"\n";
}
signed main() {
	solve();
	return 0;
}

I.除法移位

I-除法移位_河南萌新联赛2024第(一)场:河南农业大学 (nowcoder.com)

这个题目也是贪心,因为是S最大,而且S最大的要求是必须左边第一个元素必须是我们可以做到的最大值。

#include<bits/stdc++.h>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 2e14 + 10;
const int mod = 1e9 + 7;
int a[N];
inline void solve() {
	int n,t;
	cin>>n>>t;
	int mx=-1;
	for(int i=1;i<=n;i++) cin>>a[i],mx=max(mx,a[i]);
	if(a[1]==mx){ cout<<"0\n";return ;}
	mx=-1;
	int ans;
	for(int i=n;i>=max(1ll,n-t+1);i--)
	{
		if(a[i]>mx)
		{
			mx=a[i];
			ans=(n-i)+1;
		}
	}	
	cout<<ans<<"\n";
}
signed main() {
	solve();
	return 0;
}

K.图上计数(Easy)

K-图上计数(Easy)_河南萌新联赛2024第(一)场:河南农业大学 (nowcoder.com)

贪心~

考虑n<=1是只能分成两部分,反之将n分成相近的两部分直接相乘,这样的乘积最大(基本不等式)。

#include<bits/stdc++.h>
#define int long long
#define TEST int T;cin>>T;while(T--)
#define lowbit(x) x&(-x)
using namespace std;
const int N = 200010;
const int M = 2e14 + 10;
const int mod = 1e9 + 7;
inline void solve() {
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int u,v;
		cin>>u>>v;
	}
	if(n<=1) 
	{
		cout<<"0\n";
	}
	else
	{
		cout<<(n/2*(n-n/2))<<"\n";
	}
}
signed main() {
	solve();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值