黑马程序员技术交流社区

标题: 三色旗 [打印本页]

作者: wangxiaopang    时间: 2016-7-13 00:01
标题: 三色旗
  1. //
  2. //  main.c
  3. //  三色棋
  4. //
  5. //
  6. /*
  7. Algorithm Gossip: 三色棋
  8. 说明
  9. 三色旗的问题最早由E.W.Dijkstra所提出,他所使用的用语为Dutch Nation Flag(Dijkstra为荷兰人),而多数的作者则使用Three-Color Flag来称之。


  10. 假设有一条绳子,上面有红、白、蓝三种颜色的旗子,起初绳子上的旗子颜色并没有顺序,您希望将之分类,并排列为蓝、白、红的顺序,要如何移动次数才会最少,注意您只能在绳子上进行这个动作,而且一次只能调换两个旗子。
  11. 解法
  12. 在一条绳子上移动,在程式中也就意味只能使用一个阵列,而不使用其它的阵列来作辅助,问题的解法很简单,您可以自己想像一下在移动旗子,从绳子开头进行,遇到蓝色往前移,遇到白色留在中间,遇到红色往后移,如下所示:
  13. 只是要让移动次数最少的话,就要有些技巧:
  14. 如果图中W所在的位置为白色,则W+1,表示未处理的部份移至至白色群组。
  15. 如果W部份为蓝色,则B与W的元素对调,而B与W必须各+1,表示两个群组都多了一个元素。
  16. 如果W所在的位置是红色,则将W与R交换,但R要减1,表示未处理的部份减1。
  17.  
  18. 注意B、W、R并不是三色旗的个数,它们只是一个移动的指标;什幺时候移动结束呢?一开始时未处理的R指标会是等于旗子的总数,当R的索引数减至少于W的索引数时,表示接下来的旗子就都是红色了,此时就可以结束移动
  19. */
  20. #include <stdio.h>
  21. #include <string.h>
  22. int main(int argc, const char * argv[]) {
  23.     char color[] = "BWRBWRBRRWWBBWW";
  24.     long len = strlen(color);
  25.     int start = 0;
  26.     long end = len - 1;
  27.     int count = 0;
  28.     while (start < end) {
  29.         if(color[start] != 'R'){
  30.             start++;
  31.         }else if (color[end] != 'B') {
  32.             end--;
  33.         }else if(color[start] == 'R' && color[end] == 'B'){
  34.             char ch;
  35.             ch = color[start];
  36.             color[start] = color[end];
  37.             color[end] = ch;
  38.             count++;
  39.         }
  40.     }
  41.     for (int i = 0; i < len ; i++) {
  42.         if(color[i] == 'R'){
  43.             end = i;
  44.             break;
  45.         }
  46.     }
  47.     start = 0;
  48.     while (start < end) {
  49.         if(color[start] != 'W'){
  50.             start++;
  51.         }else if(color[end] != 'B'){
  52.             end--;
  53.         }else if(color[start] == 'W' && color[end] == 'B'){
  54.             char ch;
  55.             ch = color[start];
  56.             color[start] = color[end];
  57.             color[end] = ch;
  58.             count++;
  59.         }
  60.     }
  61.     for (int i = 0 ; i < len ; i++) {
  62.         if(color[i] == 'B')
  63.             start = i;
  64.     }
  65.     end = len - 1;
  66.     while (start < end) {
  67.         if(color[start] != 'R'){
  68.             start++;
  69.         }else if(color[end] != 'W'){
  70.             end--;
  71.         }else if(color[start] == 'R' && color[end] == 'W'){
  72.             char ch;
  73.             ch = color[start];
  74.             color[start] = color[end];
  75.             color[end] = ch;
  76.             count++;
  77.         }
  78.     }
  79.     printf("%s\n",color);
  80.     printf("%d\n",count);
  81.    
  82. }
复制代码

作者: wjk930726    时间: 2016-7-13 00:06
这是啥……
作者: 不想长大    时间: 2016-7-13 00:07
厉害
作者: wangxiaopang    时间: 2016-7-13 00:09
wjk930726 发表于 2016-7-13 00:06
这是啥……

三色旗的一个代码实现,没有写什么注释
作者: wjk930726    时间: 2016-7-13 00:13
wangxiaopang 发表于 2016-7-13 00:09
三色旗的一个代码实现,没有写什么注释

根本看不懂……(本条值一个黑马币)
作者: 不想长大    时间: 2016-7-13 00:20
wjk930726 发表于 2016-7-13 00:13
根本看不懂……(本条值一个黑马币)

66666
作者: wjk930726    时间: 2016-7-13 00:32
不想长大 发表于 2016-7-13 00:20
66666

朋友,那这串代码里面用到ASCII码了,但是这样的意义是什么呢
作者: hbpiaoyi    时间: 2016-7-13 08:50
太长的代码,厉害
作者: ZzzZZzz    时间: 2016-7-13 10:42
强啊! 瞻仰大神!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2