The 2020 ICPC Asia Taipei-Hsinchu Site Programming Contest C. Pyramid 题解

1.题目链接

https://codeforces.com/gym/102835/problem/C

2.题意

一个金字塔形状的网格,从塔尖向下放小球,每个点有一个开关可以使得小球在此处向左或者向右,初始状态下所有开关均向左。当小球经过一个开关会使得开关的状态翻转。给定金字塔的层数n,求第k个小球到塔底时位于哪一列。

3.题解

对于一个开关,若有x个小球经过此处,显然它会把 ⌈ x 2 ⌉ \lceil\frac{x}{2}\rceil 2x个小球向左传送,会把 ⌊ x 2 ⌋ \lfloor\frac{x}{2}\rfloor 2x个小球向右传送。由此我们可以自顶向下推出每一层的每个开关处有多少小球经过。知道了每个开关处有多少小球经过有什么用呢?如果我们知道了在一个小球到达某开关之前此处有多少小球经过,之前有奇数个经过那么本次就向右,之前有偶数个那么本次就向左,由此就能得到小球在这个开关的走向。
所以我们可以先求出前k-1个小球的分布结果,之后就能方便的求出第k个小球在每一层的走向,进而得到最后的结果。
比如我们要求n=5,k=16的结果。我们可以先求出前15个小球的分布状态,再据此求得最终答案。
在这里插入图片描述

时间复杂度 O ( n 2 ) O(n^2) O(n2)

4.代码

#include<stdio.h>
#define MAXN 10005

int T,n,k;

int main()
{
	scanf("%d",&T);
	while(T--)
	{
		int v[2][MAXN];
		scanf("%d%d",&n,&k);
		if(n==1)
		{
		    puts("0");
		    continue;
		}
		v[0][0]=k-1;
		int ans=0;
		if(v[0][0]%2) ans++;
		for(int i=1;i<n-1;i++)
		{
			int cnt=0;
			int last=0;
			for(int j=0;j<i;j++)
			{
				v[i%2][cnt++]=last+(v[(i-1)%2][j]+1)/2;
				last=v[(i-1)%2][j]/2;
			}
			v[i%2][cnt]=last;
			if(v[i%2][ans]%2) ans++; 
		}
		printf("%d\n",ans);
	}
	return 0;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值