打卡信奥刷题(1685)用C++实现信奥 P8046 [COCI 2015/2016 #4] CHEWBACCA

P8046 [COCI 2015/2016 #4] CHEWBACCA

题目背景

本套赛题 T3 为 P8053

题目描述

一棵 n n n 个节点的 k k k 级树是按照如下方式构造出来的:

  • 首先,新建根节点,并将其编号为 1 1 1
  • 随后重复如下步骤直至节点总数恰好为 n n n
    • 设上一个新增节点的编号为 x x x
    • 在上一层中从左往右找到第一个儿子个数 < k <k <k 的节点。
      • 如果该节点上没有儿子,则在该节点下新增一个儿子节点,编号为 x + 1 x+1 x+1,并在点 x + 1 x+1 x+1 和我们找到的该父亲节点之间连一条长度为 1 1 1 的边。
      • 否则,在该节点最近添加的儿子节点的右边新增一个儿子节点,编号为 x + 1 x+1 x+1,并在点 x + 1 x+1 x+1 和我们找到的该父亲节点之间连一条长度为 1 1 1 的边。
    • 如果在当前层没有找到儿子个数 < k <k <k 的节点,则跳到下一层。

例如,下图为按照如上方法构造出来的包含 9 9 9 个节点的 3 3 3 级树:

现在,你得到了这棵包含 n n n 个节点的 k k k 级树,你需要回答 q q q 次询问。每次询问给定两个整数 x , y x,y x,y,你需要回答在该树中节点 x x x 到节点 y y y 的最短路径长度。

输入格式

第一行输入三个整数 n , k , q n,k,q n,k,q,分别表示树的节点数、级数和询问次数。
随后 q q q 行,每行输入两个整数 x , y x,y x,y,表示本次询问的两个节点。

输出格式

输出 q q q 行,每行一个整数,表示节点 x x x 到节点 y y y 的最短路径长度。

输入输出样例 #1

输入 #1

7 2 3
1 2
2 1
4 7

输出 #1

1
1
4

输入输出样例 #2

输入 #2

9 3 3
8 9
5 7
8 4

输出 #2

2
2
3

说明/提示

【样例 1 解释】

下图是样例 1 中构造出来的树:

不难发现,对于第 1 1 1 2 2 2 次询问,由于节点 2 2 2 是节点 1 1 1 的儿子节点,因此这两个点之间的最短路径长度恰好为 1 1 1。而对于第 3 3 3 次询问,一条最短路径是 4 → 2 → 1 → 3 → 7 4\rightarrow 2\rightarrow 1\rightarrow 3\rightarrow 7 42137。因此其最短路径长度为 4 4 4

【样例 2 解释】

样例 2 构造出来的树见『题目描述』部分。

【数据范围】

对于 20 % 20\% 20% 的数据,保证 1 ⩽ n , q ⩽ 1000 1\leqslant n,q\leqslant 1000 1n,q1000
对于 50 % 50\% 50% 的数据,保证 1 ⩽ n ⩽ 1 0 5 1\leqslant n\leqslant 10^5 1n105
对于所有数据, 1 ⩽ n ⩽ 1 0 15 1\leqslant n\leqslant 10^{15} 1n1015 1 ⩽ k ⩽ 1000 1\leqslant k\leqslant 1000 1k1000 1 ⩽ q ⩽ 1 0 5 1\leqslant q\leqslant 10^5 1q105

【题目来源】

本题来源自 COCI 2015-2016 CONTEST 4 T4 CHEWBACCA,按照原题数据配置,满分 120 120 120 分。

Eason_AC 翻译整理提供。

C++实现

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
#define pb emplace_back
ll n,k,q,x,y,ans,i,j;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>k>>q;
	for(i=1;i<=q;i++)
	{
		cin>>x>>y;
		if(k==1)
		{
			cout<<abs(x-y)<<endl;
			continue;
		}
		ans=0;
		while(x!=y)
		{
			if(y>x) swap(x,y);
			x=(x+k-2)/k;
			ans++;
		}
		cout<<ans<<endl;
	}
	return 0;
}

在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值