博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【FJOI2015】金币换位问题
阅读量:6160 次
发布时间:2019-06-21

本文共 3476 字,大约阅读时间需要 11 分钟。

Description

  桌子上有2N+2个位置,其中前N个位置放着N个正面朝上的硬币,接下来N个位置放着反面朝上的硬币,后面两个位置为空。

  每次操作可以将任意两个相邻的硬币顺序不变地移动到空位上,那么至少要多少次操作可以将硬币移成正反相间(正面的硬币在第一个,最后两个还是空)。

  例如:当N = 4时,有一组合法解如下:

    11110000__

    __11000011

    101__00011

    1010100__1

    10101__001

    10101010__

 

Input Format

  输入一个n

Output Format

  第一行输出最少移动步数

  接下来一行为移动方案,只要输出被移动的两个非空格格子左边那个的编号。换不换行无所谓。详见样例。

Sample Input

4

Sample Output

51 4 8 6 9

Hint

对于100%的数据,2<n<=200000

 

分析:

首先需要先找到最少步数与N的关系,在考场上找到的是当N为偶数时,最少步数FN) = N * 2 - 3,当N为奇数时,FN) = N * 2 - 2,然后发现构造过程也很容易,随便搞搞就可以了。

后来成绩出来,发现这一题没分。而且,全场都没有人有拿到分。。。很多人想到是N + 1,但是没有人构造出过程。

回来之后,写了个暴力,只跑到N = 8的情况(再大内存受不了),发现答案确实是N + 1

一个学长说这很像ACM WORLD FINAL 2014的第一题,就去研究了一下,但是按那道题的方法最终的结果是0101……也没有想到怎么将它转换为1010……

后来CJK花了一整天的时间研究出一些思路,大致是分解成子问题,每次规模减小,后来又一步步完善,之后变成这样:

对于一个类似11111111000000__00的子问题,可以转换为10101010__10101010__可以在任意01之间,但是不能是1__0),步骤如下:

11111111000000__00

1__111110000001100

1001(111100__00)1100 (括号内表示下一个子问题)

子问题解决之后,再经过下面的转换:

1001(1010__1010)1100

1001(1010101010)1__0

10__(1010101010)1010

这样就将当前的子问题解决了且子问题规模每次缩小4,而每次增加的步数也是4,那么就可以符合我们的要求。

由于N > 2,所以我们的问题要从3开始处理(而且1本身就是结果,2无法解决),3456无法再分解为子问题,所以要内置3456的解法和对应子问题的解法。

然后我又在暴力的基础上加了输出所有解,找出了3456的可行方案,分别是:

32 6 4 7

41 4 8 6 9

52 7 11 3 8 11

61 6 12 9 3 10 13

然后子问题的解决方案:

36 2 5

48 1 4 7

58 3 11 2 7

610 2 12 9 6 3

3来举个例子,当规模为3的子问题出现的时候,应该是这样:

1__1(11100000)1100

然后第一步将第67个位置上的0移开,变成1001(11100__0)1100

接下来依次操作:

1001(1__00110)1100

1001(1010__10)1100

然后就可以解决外面的子问题了。

现在需要确定操作的规律,我们定义当前子问题的规模为N,起点为L,上一步操作为M,任意举一个例子N = 11的情况:

1111111111100000000000__

11111111111000000000__00        N = 11   L = 0   M = 21 = L + N * 2 - 1

1__111111110000000001100        N = 11   L = 0   M = 2 = L + 2

1001(111111100000__00)1100        N = 7   L = 4   M = 17 = L + N * 2 - 1

1001(1__1111000001100)1100        N = 7   L = 4   M = 6 = L + 2

1001(1001(11100__0)1100)1100        N = 3   L = 8   M = 14 = L + 6

1001(1001(1__00110)1100)1100        N = 3   L = 8   M = 10 = L + 2

1001(1001(1010__10)1100)1100        N = 3   L = 8   M = 13 = L + 5

1001(1001101010101__0)1100        N = 7   L = 4   M = 18 = L + N * 2

1001(10__101010101010)1100        N = 7   L = 4   M = 7 = L + 3

100110101010101010101__0        N = 11   L = 0   M = 22 = L + N * 2

10__10101010101010101010        N = 11   L = 0   M = 3 = L + 3

1010101010101010101010__        N = 11   L = 0   M = 23 = L + N * 2 + 1

从上面的过程中,我们可以发现一些规律,每次缩小规模时,解决子问题之前的操作都是L + N * 2 - 1 和 L + 2,而解决子问题之后的操作都是L + N * 2L + 3,中间规模为36的子问题特殊解决,然后大问题的最后一部都是将末尾两个移到前面,因为解决规模为36的子问题需要的步骤分别是36,加上最后一步,需要的操作数刚好是N + 1

 

代码:

 

1 #include 
2 int n, l; 3 int main () 4 { 5 scanf ("%d", &n); 6 printf ("%d\n", n + 1); 7 if (n < 7) 8 { 9 switch (n)10 {11 case 3: printf ("2 6 4 7 "); break;12 case 4: printf ("1 4 8 6 9 "); break;13 case 5: printf ("2 7 11 3 8 11 "); break;14 case 6: printf ("1 6 12 9 3 10 13 "); break;15 }16 return 0;17 }18 for (l = 0; n >= 7; n -= 4, l += 4)19 printf ("%d %d ", l + (n << 1) - 1, l + 2);20 switch (n)21 {22 case 3: printf ("%d %d %d ", l + 6, l + 2, l + 5); break;23 case 4: printf ("%d %d %d %d ", l + 8, l + 1, l + 4, l + 7); break;24 case 5: printf ("%d %d %d %d %d ", l + 8, l + 3, l + 11, l + 2, l + 7);break;25 case 6: printf ("%d %d %d %d %d %d ", l + 10, l + 2, l + 12, l + 9, l + 6, l + 3); break;26 }27 for (l -= 4, n += 4; l >= 0; l -= 4, n += 4)28 printf ("%d %d ", l + (n << 1), l + 3);29 n -= 4;30 printf ("%d ", (n << 1) + 1);31 }

 

 

 

 

转载于:https://www.cnblogs.com/lightning34/p/4384537.html

你可能感兴趣的文章
Webpack 2 中一些常见的优化措施
查看>>
移动端响应式
查看>>
js中var、let、const的区别
查看>>
简洁优雅地实现夜间模式
查看>>
react学习总结
查看>>
在soapui上踩过的坑
查看>>
MySQL的字符集和字符编码笔记
查看>>
ntpd同步时间
查看>>
Maven编译时跳过Test
查看>>
Spring Boot 整合Spring Security 和Swagger2 遇到的问题小结
查看>>
Apache通过mod_php5支持PHP
查看>>
java学习:jdbc连接示例
查看>>
Silverlight 如何手动打包xap
查看>>
禁用ViewState
查看>>
Android图片压缩(质量压缩和尺寸压缩)
查看>>
nilfs (a continuent snapshot file system) used with PostgreSQL
查看>>
【SICP练习】150 练习4.6
查看>>
HTTP缓存应用
查看>>
KubeEdge向左,K3S向右
查看>>
DTCC2013:基于网络监听数据库安全审计
查看>>