[GDKOI 2015] 青蛙跳环

题意

  给定 n 个标号为 0, 1, 2, ..., n-1 的点.

  一只青蛙在点 i 能够跳往 (2 * i) % n 和 (2 * i + 1) % n .

  若该青蛙从点 0 出发, 是否能够跳出一条哈密顿回路, 如果可以, 还要找到字典序最大的.

  2 <= N <= 10000 .

分析

  我们先研究一些小的情形.

  暴力打表发现, 当 n 为奇数时, 一定无解.

  接下来保证 n 为偶数.

  当 n 为偶数时, 2 * (n / 2) = 0 (mod n) .

  所以 i 和 i + n / 2 能够跳到的点是相同的, 我们考虑把它们缩点.

  以 n = 8 为例, 画出这样一个图.

          ----------------------------------------         

          ↓             ↑

         ---------    --------     --------    ---------

   ←←←   | 0 |    | 1 | <-  | 2 |     |  3 |      →→→

   |        |    |  ->   |    | -> |    | <-   |    |       |

   →→→   | 4 |    | 5 |   | 6 |     | 7 |   ←←←

         ---------    ----------   --------    ----------

                  ↓             ↑

                  ----------------------------------------

  发现每个点不仅有且仅有两条出边, 而且有且仅有两条入边.

  而我们的目标是每个点经过两次, 所以我们的目标相当于是经过所有的边, 直接求欧拉回路.

实现

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cctype>
 5
 6 const int N = 10005;
 7
 8 int n, Lis[N], tot;
 9 bool v[N];
10
11 void Dfs(int x) {
12     if (!v[x << 1 | 1]) {
13         v[x << 1 | 1] = true;
14         Dfs((x << 1 | 1) % (n >> 1));
15         Lis[++tot] = x << 1 | 1;
16     }
17     if (!v[x << 1]) {
18         v[x << 1] = true;
19         Dfs((x << 1) % (n >> 1));
20         Lis[++tot] = x << 1;
21     }
22 }
23
24 int main(void) {
25     #ifndef ONLINE_JUDGE
26         freopen("frog.in", "r", stdin);
27     #endif
28
29     scanf("%d", &n);
30     if (n & 1) return puts("-1"), 0;
31
32     Dfs(0), Lis[++tot] = 0;
33     while (tot > 0) printf("%d ", Lis[tot--]); puts("");
34
35     return 0;
36 }
时间: 2024-12-20 14:35:03

[GDKOI 2015] 青蛙跳环的相关文章

【剑指Offer-循环和递归】面试题10.2:青蛙跳台阶

题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). 思路 当台阶为1级时,共1种方法:当为2级时,共2种方法:当为3级时,共3中方法.以此类推,有n级台阶时,共f(n)=f(n-1)+f(n-2), n>2, f(1) = 1, f(2) = 2. 对应的代码如下: class Solution { public: int jumpFloor(int number) { int a[2] = {1, 2}; if(nu

动态规划--青蛙跳

Description 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点:0,1,……,L(其中L是桥的长度).坐标为0的点表示桥的起点,坐标为L的点表示桥的终点.青蛙从桥的起点开始,不停的向终点方向跳跃.一次跳跃的距离是s到t之间的任意正整数(包括s,t).当青蛙跳到或跳过坐标为L的点时,就算青蛙已经跳出了独木桥. 题目给出独木桥的长度L,

青蛙跳台阶问题

题目:一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级.求该青蛙跳上一个n 级的台阶总共有多少种跳法. 我的思路:最开始我的思路是把这个看成是一个数学问题,n=i*1+k*2先把所有可能满足这个公式的i和k求出来.然后在对i和k做排列组合.很明显i的范围应该是0<i<=n,所以我们已i开始迭代.下面贴上代码吧.把注释都写上! public int JumpFloor(int target) { int step = 0; for (int i = 0; i <= target; i++

青蛙跳台阶问题-斐波拉契数列

题目1:一个台阶总共有n级,如果一次可以跳1级,也可以跳2级.求总共有多少种跳法 首先我们考虑最简单的情况,加入只有1级台阶,那显然只有一种跳法,如果有2级台阶,那就有两种跳的方法了:一种是分两次跳,每次跳1级:另外一种就是一次跳2级 现在我们来讨论一般情况.我们把n级台阶时的跳法看成是n的函数,记为f(n).当n>2时,第一次跳的时候就有两种不同的选择:一是第一次只跳1级,此时跳法数目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1):另外一种选择是第一次跳2级,此时跳法数目等于后面剩下的

剑指offer青蛙跳台阶问题

(1)一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级.求该青蛙跳上一个n 级的台阶总共有多少种跳法. //递归方式 public static int f(int n) { //参数合法性验证 if (n < 1) { System.out.println("参数必须大于1!"); System.exit(-1); } if (n == 1 || n == 2) return 1; else return f(n - 1) + f(n - 2); } //非递归方式 publ

c语言:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法?

一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法? 解:把n级台阶时的跳法记为f(n),当n>2时,第一次跳的时候有两种不同的选择:一是第一次只跳1级,此时跳法数目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1);另外一种是第一次跳2级,此时跳法数目等于后面剩下的n-2级台阶的跳法数目,即为f(n-2);因此n级台阶时的跳法为f(n)=f(n-1)+f(n-2).不难看出这实际是斐波拉契数列的变形应用,把斐波拉契数列的每一项向前移动了1位. 程序:

青蛙跳台阶的问题

#斐波纳契 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. # 假设最后一步到X级台阶,有F(X)种走法, # 这题求的就是F(11) # 因为每步可以迈1或2级台阶. # 所以最后一步到11级台阶, # 而倒数第2步可能是在第10或9级台阶. # 所以到11级台阶的走法,是到第10或9级台阶走法的和. # 同样到9级台阶的走法,是到第7或8级台阶走法的和. # ................... # F(11) # =F(9)+F(10) # =

HDU 5037(Frog-贪心青蛙跳石子)

Frog Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 1596    Accepted Submission(s): 442 Problem Description Once upon a time, there is a little frog called Matt. One day, he came to a river.

青蛙跳-算法

/***一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法.*/public class Solution { public int JumpFloor(int target) { if(target<=2){ return target; } int start=1; int end =2; end=this.sum(start,end,3,target); return end; }/***分析出数据: 1 2 3 5 8*start 前一个台阶跳法*e