XCPC真题 - Binary Tree —— 性质,贪心

题目链接

题意:

给出一个完全二叉树,顺序编号。每一点的权值为其编号。
从根节点开始走,初始总和 sum 为0。
每次可以选择左右儿子中的一个往下走,可以选择让 sum 减去其权值 或者 加上其权值。
输出一条到第 k 层的路径,满足 sum 恰好为 N。
1 ≤ N ≤ 1 0 9 1 \leq N \leq 10^{9} 1N109
N ≤ 2 K ≤ 2 60 N \leq 2^{K} \leq 2^{60} N2K260

分析:

应该是完全二叉树的性质,满足一定存在这样的路径。
但是从根节点往下走不好判断左右儿子走哪个,加还是减。

可以从叶节点往上走,只需要判断父节点加还是减

叶子节点很多,但是从前往后走不了多远就能找到满足的。

贪心搞:从下往上走,一开始碰见的都是比较大的。
如果当前的 sum 小于 n 的话,那么就加上;否则就减去。
到根节点如果正好是 n 的话,那么这条路径就是满足的。

应该是因为这刚好是完全二叉树,所以这样贪心是正确的。

Code:

//https://vjudge.net/problem/HDU-5573
#include<bits/stdc++.h>
using namespace std;

/**/

const int N = 200010, mod = 1e9+7;
int T, n, m;
int a[N], flag;
int path[N];
char f[N];

void dfs(int x, int sum, int flor)
{
	path[flor] = x;
	
	if(flor == 0){
		if(sum == n) flag = 1;
		return;
	}
	if(flag) return;
	
	if(sum <= n) //没拿之前总和比n小,就拿 
	{
		f[flor] = '+';
		dfs(x/2, sum+x, flor-1);
	}
	else{ //没拿之前总和比n大,不拿 
		f[flor] = '-';
		dfs(x/2, sum-x, flor-1);
	}
}

signed main(){
	Ios;
	cin >> T;

	for(int ca = 1; ca <= T; ca ++)
	{
		int k;
		cin >> n >> k;
		
		flag = 0;
		for(int i = (1ll<<k-1); i < (1ll<<k); i++)
		{
			dfs(i, 0, k);
			if(flag) break;
		}
		
		cout << "Case #" << ca << ":\n";
		for(int i=1;i<=k;i++) cout << path[i] << " " << f[i] << "\n";
	}
	
	return 0;
} 

经验:

题目既然没说有不满足的情况,那就说明一定能满足。
但是在哪个地方满足不知道。
所以要敢于暴力,因为不知道走到哪里就break了。

以后碰见没说 -1 的题要敢于暴力。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值