2018北京ICPC D. Frog and Portal(构造)

探讨了通过在河中荷叶上设置传送门来控制青蛙过河路径的方法,实现特定数量的过河方式,涉及数学序列、逻辑思维与算法构造。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

D : Frog and Portal

时间限制:1000ms  单点时限:1000ms  内存限制:512MB

描述

A small frog wants to get to the other side of a river. The frog is initially located at one bank of the river (position 0) and wants to get to the other bank (position 200). Luckily, there are 199 leaves (from position 1 to position 199) on the river, and the frog can jump between the leaves. When at position p, the frog can jump to position p+1 or position p+2.

How many different ways can the small frog get to the bank at position 200? This is a classical problem. The solution is the 201st number of Fibonacci sequence. The Fibonacci sequence is constructed as follows: F1=F2=1;Fn=Fn-1+Fn-2.

Now you can build some portals on the leaves. For each leaf, you can choose whether to build a portal on it. And you should set a destination for each portal. When the frog gets to a leaf with a portal, it will be teleported to the corresponding destination immediately. If there is a portal at the destination, the frog will be teleported again immediately. If some portal destinations form a cycle, the frog will be permanently trapped inside. Note that You cannot build two portals on the same leaf.

Can you build the portals such that the number of different ways that the small frog gets to position 200 from position 0 is M?

输入

There are no more than 100 test cases.

Each test case consists of an integer M, indicating the number of ways that the small frog gets to position 200 from position 0. (0 ≤ M < 232)

输出

For each test case:

The first line contains a number K, indicating the number of portals.

Then K lines follow. Each line has two numbers ai and bi, indicating that you place a portal at position ai and it teleports the frog to position bi.

You should guarantee that 1 ≤ K, ai, bi ≤ 199, and ai ≠ aj if i ≠ j. If there are multiple solutions, any one of them is acceptable.

样例输入

0
1
5

样例输出

2
1 1
2 1
2
1 199
2 2
2
4 199
5 5

 

题意:

青蛙在一条河的左边,它想去河的对岸,河中间有199个荷叶,编号1到199从左往右排成一排,可以假设河左岸位置是0,对岸位置为200,青蛙每次可以向右跳1步或者2步,现在你可以在其中一些荷叶上面设置传送装置,一旦青蛙到达有着传送装置的荷叶,那么它将会被强制瞬移到传送装置设置的位置(可能发生连锁反应),其中一个荷叶上最多只能设置一台传送装置,问如何设置传送装置使得到对岸有刚好m种不同方案

 

思路:

构造题嘛,理论上不停拿数据测AC代码看输出就会做了,因为重要的是怎么构造

可以从2的次方上考虑,假设你在位置x上,求到达位置200,方案数刚好为m,该如何设置传送装置?

  • 如果当前m是偶数,那么很显然可以在位置x+1上设一个传到x+3的传送门,在位置x+2上设一个传到x+1的传送门,这样的话你无论往前跳2步还是1步都是到达位置x+3上,这样问题就变成了你在位置x+3上,求到达位置200,方案数刚好为m/2,该如何设置传送装置
  • 如果当前m是奇数,那么很显然可以在位置x+1上设一个直接传到终点的传送门,在位置x+2不设传送门,这样问题就变成了你在位置x+2上,求到达位置200,方案数刚好为m-1,该如何设置传送装置

搞定,注意特判m=1和m=0的情况

 

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
#define LL long long
#define mod 1000000007
LL F[55] = {1,1,2};
int s1[250], s2[250];
int main(void)
{
	LL n;
	int cnt, i, now;
	for(i=3;i<=50;i++)
		F[i] = F[i-1]+F[i-2];
	while(scanf("%lld", &n)!=EOF)
	{
		if(n==0)
			printf("2\n1 1\n2 2\n");
		else if(n==1)
			printf("2\n1 199\n2 2\n");
		else
		{
			now = 1, cnt = 0;
			while(n!=1)
			{
				if(n%2==0)
				{
					s1[++cnt] = now, s2[cnt] = now+2;
					s1[++cnt] = now+1, s2[cnt] = now;
					now += 3;
				}
				else
				{
					s1[++cnt] = now, s2[cnt] = 199;
					now += 2;
					s1[++cnt] = now, s2[cnt] = now+2;
					s1[++cnt] = now+1, s2[cnt] = now;
					now += 3;
				}
				n /= 2;
			}
			s1[++cnt] = now-1, s2[cnt] = 199;
			printf("%d\n", cnt);
			for(i=1;i<=cnt;i++)
				printf("%d %d\n", s1[i], s2[i]);
		}
	}
	return 0;
}

 

<think>好的,我现在需要帮助用户查找ICPC南京区域赛题目I(Counter)的解法或讨论。首先,我需要确认用户提到的具体是哪一年的比赛。根据用户提供的引用,引用了2020、2021、2022年的南京区域赛内容,但问题I(Counter)可能出现在不同年份的比赛中。 接下来,我需要检查提供的引用内容,看看是否有提到Problem I或Counter相关的信息。引用[1]提到用户请求关于序列的问题,可能与Counter题目的内容相关。引用[2]提到关于处理ai=0的情况,这可能与问题中的某些条件有关。引用[3]是2020年的题解,其中包含n的范围,可能与题目中的参数相关。引用[4]和[5]分别涉及其他问题,可能不直接相关。 假设用户指的是2022年的题目,因为引用[1]提到了2022南京补题记录中的问题I。不过,引用中并没有直接给出问题I的解法。可能需要进一步分析题目可能的解法方向。 根据常见的竞赛题目类型,Counter可能涉及计数问题,可能与组合数学、动态规划或数学推导相关。例如,可能需要找到满足特定条件的排列数或序列数。结合引用[2]中提到的处理ai=0的情况,可能题目中存在某种递推关系或需要排除某些特殊情况。 此外,引用[3]中提到的n的范围到1e6,可能意味着需要线性或O(n)的算法,而不是暴力解法。这可能涉及数学公式或预处理技巧。例如,快速幂、组合数预处理或模运算优化。 可能的解决步骤包括: 1. 确定题目的具体要求,例如计算满足某种条件的计数器值。 2. 分析输入条件和约束,确定算法复杂度要求。 3. 推导数学公式,可能需要递推关系或组合数学的知识。 4. 处理特殊情况,如ai=0的情况,如引用[2]所述。 5. 实现高效的代码,可能利用动态规划或数学优化。 由于用户提供的引用中没有详细的题解,可能需要根据常见的竞赛题目模式进行推测。例如,如果题目涉及计数满足某种排列条件的序列,可能需要使用排列组合或容斥原理。或者,如果涉及动态规划,可能需要状态转移方程的推导。 在生成回答时,需要结合可能的解题方向,并引用相关的引用内容来支持解释。例如,引用[2]提到的处理ai=0的情况可能涉及到排除无效情况或计算贡献,引用[3]中的n范围提示需要高效算法。 最后,生成相关问题,帮助用户进一步理解题目可能的解法和优化方向。</think>### ICPC南京区域赛题目I(Counter)解法分析 根据现有信息推测,题目I(Counter)可能与**序列计数**或**数学推导**相关。结合引用[2]中提到的"ai=0"处理方式,以及竞赛题常见模式,解法可能涉及以下关键点: 1. **问题建模** - 需要计算满足特定条件的序列数量,例如:相邻元素关系、模数约束等 - 可能涉及排列组合数学,例如构造满足$a_i \equiv c \mod m$条件的序列 2. **关键观察** - 当$a_i=0$时,可通过数学推导直接计算其对答案的贡献[^2] - 可能存在递归关系或快速幂优化,尤其当$n \leq 10^6$时需要线性算法[^3] 3. **算法设计** ```python # 示例伪代码结构(假设为递推关系) MOD = 10**9+7 n = int(input()) dp = [0]*(n+1) dp[0] = 1 for i in range(1, n+1): dp[i] = (dp[i-1] * k) % MOD # k为状态转移参数 print(dp[n]) ``` 4. **复杂度优化** - 预处理阶乘/逆元加速组合数计算 - 矩阵快速幂优化递推关系 - 利用模运算性质减少计算量[^4]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值