牛客周赛88

目录

[D. 漫步](#D. 漫步)

[E. 密藏](#E. 密藏)

[F. 回响](#F. 回响)


D. 漫步

x + z 中包含了所有 x 中为 1 的二进制位,也就是说 x 加上 z 后不能破坏 x 中本身二进制位为 1 的位,因此只要找到 x 的二进制位中第一个为 0 的位,让这一位为 1,赋值给 z 即可。

cnt 是实际位数,pos 是处于第几位,但 pos 是从 0 开始的,二进制表示中最低位是第 0 位。所以最高位实际上是 cnt - 1。

复制代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 5, INF = 1e18;

int T, n, ans;
string s;

int fpow(int a, int b)
{
	int res = 1;
	while (b)
	{
		if (b & 1)
			res *= a;
		a *= a;
		b >>= 1;
	}
	return res;
}

signed main()
{
	cin >> T;
	while (T --)
	{
		int x;
		cin >> x;
		int cnt = 0, pos = 0;
		int tx = x;
		while (tx != 0)
			tx >>= 1, cnt ++;        // 计算 x 的二进制表示有多少位
		while (x & 1)
			x >>= 1, pos ++;         // 找到第一个为 0 的二进制位
		if (pos == cnt)              // 因为 pos 是从下标 0 开始,所以这里两个相等就已经是超过了最高位了
		{
			cout << "-1" << '\n';
			continue;
		}
		int z = fpow(2, pos);
		cout << z << '\n';
	}
	return 0;
}

E. 密藏

凡是想到用贪心做的,都先想一想能不能 dp。

dp [ i ] [ 0 / 1 ] 表示到前 i 号点的最大收益,0 和 1 分别表示两个世界。dp 的无后效性是指对于前 i 个点的答案,与 i 之后的点无关。每一个 i 都是存的以第 i 号点为终点的最优解。

定义好 dp 之后就是枚举状态转移的所有情况。每一个点都可以由当前世界的前一个点或者另外一个世界的前一个点转移来,区别是后者要加判断条件。因为每个点都可能有两种转移来的方式,所以要取 max。

复制代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 5, INF = 1e18;

int T, n, k, ans, a[N], b[N], dp[N][2];
string s;

signed main()
{
	cin >> n >> k;
	for (int i = 1; i <= n; i ++)
		cin >> a[i];
	for (int i = 1; i <= n; i ++)
		cin >> b[i];
	for (int i = 1; i <= n; i ++)
		dp[i][0] = -1, dp[i][1] = -1;
	dp[1][0] = a[1];
	for (int i = 2; i <= n; i ++)
	{
		if (dp[i - 1][0] != -1)
		{
			dp[i][0] = dp[i - 1][0] + a[i];
			if (dp[i - 1][0] - k >= 0)
				dp[i][1] = dp[i - 1][0] - k + b[i];
		}
		if (dp[i - 1][1] != -1)
		{
			dp[i][1] = max(dp[i][1], dp[i - 1][1] + b[i]);
			if (dp[i - 1][1] - k >= 0)
				dp[i][0] = max(dp[i][0], dp[i - 1][1] - k + a[i]);
		}
	}
	ans = max(dp[n][0], dp[n][1]);
	cout << ans;
	return 0;
}

F. 回响

先处理第一堆石子前面的格子,然后处理第一堆到最后一堆,最后处理最后一堆以及后面的所有。

对于夹在有石子的格子中间的空格,就是受到两端石子数的限制,因此看一下距离能否满足,只可长不可短,如果长还要看奇偶性能否满足加一减一微调。

复制代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 5, INF = 1e18;

int T, n, cnt, ans[N], a[N], b[N], pos[N];
string s;

signed main()
{
	cin >> n;
	for (int i = 1; i <= n; i ++)
	{
		cin >> a[i];
		if (a[i] != 0)
		{
			cnt ++;
			b[cnt] = a[i];
			pos[cnt] = i;
		}
	}
	if (pos[1] != 1)
		for (int i = 1; i < pos[1]; i ++)
			ans[i] = b[1] + pos[1] - i;
	for (int i = 1; i < cnt; i ++)
	{
		ans[pos[i]] = b[i];
		int t1 = abs(b[i + 1] - b[i]), t2 = pos[i + 1] - pos[i];
		if (t1 > t2)
		{
			cout << "-1";
			return 0;
		}
		if ((t2 - t1) % 2 != 0)
		{
			cout << "-1";
			return 0;
		}
		int cnt = 1;
		for (int j = pos[i] + 1; j < pos[i + 1]; j ++)
		{
			if (cnt <= t1)
			{
				if (b[i] < b[i + 1])
					ans[j] = b[i] + cnt;
				else
					ans[j] = b[i] - cnt;
				cnt ++;
			}
			else
			{
				if (ans[j - 1] == b[i + 1])
					ans[j] = ans[j - 1] - 1;
				else
					ans[j] = ans[j - 1] + 1;
			}
		}
	}
	ans[pos[cnt]] = b[cnt];
	for (int i = pos[cnt] + 1; i <= n; i ++)
		ans[i] = ans[i - 1] + 1;
	for (int i = 1; i <= n; i ++)
		cout << ans[i] << ' ';
	return 0;
}
相关推荐
雪域迷影4 小时前
C++中编写UT单元测试用例时如何mock非虚函数?
开发语言·c++·测试用例·gmock·cpp-stub开源项目
sheeta19986 小时前
LeetCode 每日一题笔记 日期:2025.11.24 题目:1018. 可被5整除的二进制前缀
笔记·算法·leetcode
是小胡嘛9 小时前
C++之Any类的模拟实现
linux·开发语言·c++
Want59511 小时前
C/C++跳动的爱心①
c语言·开发语言·c++
lingggggaaaa12 小时前
免杀对抗——C2远控篇&C&C++&DLL注入&过内存核晶&镂空新增&白加黑链&签名程序劫持
c语言·c++·学习·安全·网络安全·免杀对抗
phdsky12 小时前
【设计模式】建造者模式
c++·设计模式·建造者模式
H_-H12 小时前
关于const应用与const中的c++陷阱
c++
coderxiaohan12 小时前
【C++】多态
开发语言·c++
gfdhy12 小时前
【c++】哈希算法深度解析:实现、核心作用与工业级应用
c语言·开发语言·c++·算法·密码学·哈希算法·哈希
百***060112 小时前
SpringMVC 请求参数接收
前端·javascript·算法