广东工业大学文远知行杯新生程序设计竞赛(重现赛)复习

广东工业大学文远知行杯新生程序设计竞赛(重现赛)

1,F,亚子和燐子的game

思路:

我们可以维护一个堆(里面的数都相等,其实就是一个数),每扔进去一个数,就继续维持堆中数字相等(维持方法,就是谁大谁除3),如果发现维护不了,那么就是无法实现

#include <bits/stdc++.h>
using namespace std;
#define ll     long long
typedef unsigned long long ull;
typedef pair<long long, long long> pll;
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 100;

int main()
{
	ll n, a, b, cnt = 0;
	cin >> n >> a;//把第一个数作为堆的起点
	bool flag = 1;
	for (int i = 1; i < n; ++i)
		{
			cin >> b;//后面输入n-1个数
			if (flag)
				{
					while (a != b)//尝试让a与b相等
						{
							if (a > b)a /= 3, cnt += i;//对a堆操作(里面有i个数),所以操作一次,次数加i
							if (a < b)b /= 3, cnt++;//对一个数b操作,加一次就好
							if (a == b)break;//相等跳出
							if (a < 3 && b < 3)	//如果都小于3还没有相等跳出,说明无法维护
								{
									flag = 0;
									break;
								}

						}
				}

		}
	if (flag)cout << cnt << endl;
	else cout << "Lose" << endl;
	return 0;
}

2,J,狐臭的等比数列

思路:

我们把原始a数组升序排列。会发现a[i+1]/a[i]就是公比的次幂q^k,所以我们讨论最少几个,其实就是讨论相邻的q^k(共n-1个)的k大于1的有几个,有就是加上k-1,所以我们建一个数组来存q^k,但是我们发现,q可以是分数。

我们又会发现,就算q是分数,也被a[0]*q^n的a[0]消去,所以我们可以不用管分母,提取分子即可

具体操作如下

3 ,k,玩石头a​​​​​​​

思路:

求石头堆的最大魅力值可以看成在i魅力下最小石头重量m[i](限制条件,每次放入石头重量x,必须比当前魅力值允许的小),其实你会发现就是个背包--看起来不知道魅力值范围会被t(bushi)

我们发现是有可行性的,ai<1e9,我们清楚最小数列是斐波那契数列,自己打表发现第35个值超过1e9,所以其实最多35个石头叠一起,魅力值最大100,所以最大魅力值绝对不超过3600。

我们可以按重量排序后,把魅力值当作背包容量,限制条件是m[i]在i魅力值情况下最小重量是m[i],当m[i]小于当前石头x时,得到递推式    m[i + y] = min(m[i + y], x + m[i]);从而得到每个魅力值的最小重量

#include <bits/stdc++.h>
using namespace std;
#define ll     long long
typedef unsigned long long ull;
typedef pair<long long, long long> pll;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 100;
const int M = 3600;
ll m[M + 200];//压空间,但一定注意稍微大一些,这样保证不会越界
int main()
{
	vector<pll>v;
	int n;
	cin >> n;
	int x, y;
	for (int i = 1; i <= n; ++i)
		{
			cin >> x >> y;
			v.push_back({x, y});
		}
	sort(v.begin(), v.end());//排序,是为了从小重量递推回去大重量
	memset(m, 0x3f, sizeof(m));//初始化任意魅力值石头重量inf
	m[0] = 0;//当然,魅力值0,重量0
	ll maxn = -INF;
	for (auto [x, y] : v)
		{
			for (int i = M; i >= 0; i--)//从大到小,防止后效性
				{
					if (m[i] < x)//限制条件,每次放入石头,必须比原来的大(m[i]装的是当前一个堆的石头重量,放入x是垫最下面的
						{
							m[i + y] = min(m[i + y], x + m[i]);//能放,我们就可以求出魅力值加y后石头堆的最小重量
							maxn = max(maxn, i + y);//只要有出现的魅力值,就是能够堆出来的石头堆
						}
				}
		}
	cout << maxn << endl;
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值