河南萌新联赛2024第(一)场:河南农业大学

文章目录


#题目
##A.造数
##D 小蓝的二进制询问 有时间再写
##F 两难抉择新编 有时间再写
##H 两难抉择
##I 除法移位
##K 图上计数(Easy)

##A.造数
###题目描述
给定一个整数 n ,你可以进行以下三种操作
操作1: +1
操作2; +2
操作3: ×2
问最少需要多少次操作可以将 0 转为为 n 。
输入描述:
输入包含 1行一个整数 𝑛(0≤𝑛≤10^9)
n(0≤n≤10^9 )。
输出描述:输出包含一行一个整数,表示造出 n 所需的最小操作次数。
示例1
输入
2
输出
1
示例2
输入
5
输出
3
###思路:倒着考虑,1,2需要注意,其他就是技术减1,偶数除以2

#include <iostream>
using namespace std;
int main() {
	long long n;
	cin >> n;
	int count = 0;
    if(n==1)
    {
        cout<<"1";
       return 0;
    }
	while (n > 1) //比如2的时候如果是大于0,它除以而等于1,还会进行一步,答案就不对,我当时就烦了这个错误
    {
		if (n % 2 == 0) 
            n /= 2;
//        else if (n >= 3 && (n - 1) % 4 == 0)这个是当时写的,不加这个也对
//			n--;
        else 
			n--;//注意一下奇数就行
		count++;
	}
	cout << count << endl;
	return 0;
}

##D 小蓝的二进制询问 有时间再写
##F 两难抉择新编 有时间再写
链接:https://ac.nowcoder.com/acm/contest/86639/H
来源:牛客网
##H 两难抉择
###题目描述
现在有长度为n 的数组a,你可以在两种操作中选择一种进行最多一次操作。
操作1:选择一个数 i(1≤i≤n) 使得 𝑎𝑖:=𝑎𝑖+𝑥,x 可以是[1,n] 范围内任意正整数。
操作2:
选择一个数 i (1≤i≤n) 使得 𝑎𝑖:=𝑎𝑖×𝑥,x 可以是 [1,𝑛] 范围内任意正整数。
请问进行操作后,最大的数组总和是多少?
输入描述:
输入包含两行.第一行一个正整数 n (1≤𝑛≤2×10^5) 表示数组 a 的长度。
第二行
n 个正整数 ai (1≤𝑎𝑖≤10^9 ) 表示数组 a 的元素。
输出描述:
输出包含一行一个整数,表示最大的数组总和。
示例1
输入
5
5 3 4 1 2
输出
35
说明
选择第一个数
5 , 5∗5后使得数组总和最大,25+3+4+1+2=35。
###思路:就考虑两种情况,第一种就是全是1,这个时候就是+,当不是全都是1的时候就乘

#include <iostream>
#include <algorithm>
using namespace std;
long long a[200000];
int main() {
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> a[i];
	sort(a, a + n);
	long long sum = 0;
	for (int i = 0; i < n; i++)
		sum += a[i];
	long long maxSum = 0;
	maxSum = max(maxSum, (long long)a[n - 1] * n + sum - a[n - 1]);
	if (a[n - 1] == 1)
	{
		long long ans = n;
		for (int i = 0; i < n ; i++)//刚开始这里到n-1,有点粗心。
			ans += a[i];
		maxSum = max(maxSum, ans);
	} 
	else
		maxSum = max(maxSum, sum);
	cout << maxSum << endl;
	return 0;
}

下面官方的比较简练

#include "bits/stdc++.h"
using namespace std;
int main()
{
int n;
cin >> n;
long long mx = 0, sum = 0;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++)
{
cin >> a[i];
sum += a[i];
}
for (int i = 1; i <= n; i++)
{
mx = max({mx, sum - a[i] + 1ll * a[i] * n, sum - a[i] + a[i] + n});
}
cout << mx << '\n';
}

##I 除法移位
链接:https://ac.nowcoder.com/acm/contest/86639/I
来源:牛客网

###题目描述
现在有长度为 n 的数组 a,式子 S 定义为 𝑆=𝑎1÷𝑎2÷𝑎3…÷𝑎𝑛S=a1​ ÷a2 ÷a3​ …÷an​ ,最多对数组 a 进行 t 次循环右移操作。
请问,进行第几次操作时使得 S 最大?若存在多种答案,请输出最小值。
循环右移:一次操作使数组从 𝑎1,𝑎2,𝑎3,…,𝑎𝑛形式转换为 𝑎𝑛,𝑎1,𝑎2,…,𝑎𝑛−​1 形式。
输入描述:
输入包含两行.第一行一个正整数 n,t (1≤𝑛≤2×105,0≤𝑡≤109)(1≤n≤2×105,0≤t≤109) 表示数组 a 的长度和最多的操作次数。
第二行 n 个正整数 ai(1≤𝑎𝑖≤109)(1≤a i​ ≤109 ) 表示数组 a 的元素。
输出描述:
输出包含一行一个整数,表示使得
S 最大的最小操作次数。
示例1
输入
5 10
5 3 4 1 2
输出
0
说明
操作0次时使得 𝑆=5÷3÷4÷1÷2
S=5÷3÷4÷1÷2 最大
备注:÷ 是正常除法,不是向上取整或向下取整。
###思路:找到可移动次数内最大数就行

#include<iostream>
#include<algorithm>
using namespace std;
long long a[200001],b[200001];
int main()
{
    int n;
    long long t;
    cin>>n>>t;
    int ans=0;
    for(int i=0;i<n;i++)
        cin>>a[i];
    int y;
    if(t>n)
        y=n;//超过数组之后多余的移动没用
    else
        y=t;
    long long maxx=a[n-1];
    for(int i=n-1;i>=n-y;i--)//注意这里,刚开始我i>=n-y-1,用下面的的样例证明是错的
        maxx=max(maxx,a[i]);
        
//     cout<<maxx<<endl;
    for(int i=n-1;i>=0;i--)
    {
        if(ans==t)//达到次数直接退出
            break;
        ans++;
//         cout<<ans<<endl;
        if(a[i]==maxx)
            break;   
    }
    b[0]=a[0];//先保存第一个数
     sort(a,a+n);
    if(b[0]==a[n-1])//找到的最大数如果与第一个数相同,直接输出0;
        cout<<"0";
    else
        cout<<ans;
    return 0;
}
// 5 3
// 3 4 1 2 1

##K 图上计数(Easy)
链接:https://ac.nowcoder.com/acm/contest/86639/K
来源:牛客网

###题目描述
Easy 版本和 Hard 版本唯一的区别是 Hard 版本删除的是桥,而 Easy 版本删除的是任意边。你有一张 n 个点 m 条边的无向图,你有无数次删除操作来删除任意条边以获得若干个联通块。定义联通块的大小为其所包含点个数。定义这个图的代价是:你有任意次操作,每次操作合并两个联通块,合并后联通块大小为二者之和,最后剩下两个联通块大小的乘积为此图的代价,若只有一个则代价为0。你需要最大化此图代价。
输入描述:
第一行包含两个整数 n 和 m ,图中顶点的数量和边的数量。接下来的每 m 行包含两个整数 u 和 v ,表示图中顶点 u 和 v 之间有一条无向边。(0<n≤10 6 ) (0≤𝑚≤106) (0<u,v≤n)
输出描述:
输出一个整数表示最大代价。
示例1
输入
4 3
1 2
2 3
3 4
输出
4
###思路:消除所有边,最后两个数相乘,当两个数最接近的时候就是最大值

#include<iostream>

using namespace std;
signed main()
{
    long long  n,m;
    cin>>n>>m;
    if(n%2==0)
    cout<<(n/2)*(n/2);//偶数
    else
    cout<<(n/2+1)*(n/2);//奇数
    return 0;
    
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值