一个简单的青蛙算法~~

一个哥们给了道有意思的题,我贴出来与大家分享,还有我简单解。

★问题描述:
在一条水平的瓷砖道路上,有一只迷路的小青蛙。这只青蛙可以沿着水平道
路向前或者向后,行走或者跳跃。瓷砖有两种颜色,分别为黑色和白色,青蛙所
在的位置被标记为空格。青蛙可以走到相邻(向前或者向后)的瓷砖上。
当青蛙沿着瓷砖行走时,青蛙原先所在的位置状态变为青蛙走到的位置状
态,青蛙走到的位置被标记为空格。例如,在下图中,在青蛙的前面有三块瓷砖,
在青蛙的后面有二块瓷砖。我们可以使用“BWFBBW”来表示当前的状态,其中F
表示空格(即青蛙所在的位置),B 表示瓷砖是黑色的,W 表示瓷砖是白色的。如
果青蛙向前行走,状态变为“BWBFBW”。同样的,如果青蛙向后行走,状态变为
“BFWBBW”。即青蛙的位置与相邻的瓷砖相交换。
青蛙还可以在瓷砖上跳跃,青蛙可以隔着一块瓷砖跳到下一块瓷砖上,同样
的,青蛙隔着的瓷砖状态将变化,即从W 变为B,从B 变为W,青蛙原先所在的
位置状态变为青蛙跳跃到的位置状态。例如,在下图中,当青蛙向前跳跃时,状
态变为“BWWBFW”,当青蛙向前跳跃时,状态变为“FWWBBW”。
现在要求在任意两块黑色瓷砖之间都不能有白色瓷砖,请你计算出青蛙所需
要移动(行走或者跳跃)的最小步数。
给定瓷砖的状态,请你计算出青蛙所需要移动(行走或者跳跃)的最小步数。
★数据输入:
输入有多组数据,每组输入数据的第一行为一个整数T(1≤T≤10),表示输
入数据的组数,以下T行,每行有一个字符串S,S的长度不大于100且不为空,S
只包含字符“BWF”并且只有一个字符F,表示瓷砖的状态。
★结果输出:
对于每组输入数据输出一行一个整数,表示青蛙所需要移动(行走或者跳跃)
的最小步数,如果需要超过10 步才能完成,请输出“-1”。
输入示例

WWBBFBW
WBFBWBBWBWBWBWB

根据这个算出步子就可以了.

我的解:

 

代码
    class Program
    {
        
static void Main(string[] args)
        {
            
///首先是获得输入序列
            while (true)
            {
                
int Cur, CountL = 0, CountR = 0;
                Console.WriteLine(
"请输入序列。");
                
string StrRoad = Console.ReadLine();
                
string ResvStrRoad = Reverse(StrRoad);
                Console.WriteLine(
"已经获得输入序列:" + StrRoad);
                
///之后,根据题意,先想到第一个算法:穷举。因为跳肯定比走快吧,所以每次轮到青蛙走的时候,先让它跳,如果跳之后出现了黑白+黑的情况,则换走,如果走再出错。
                
///就没办法了。每步都这样走,就会得到最优的路线。
                Regex reg = new Regex("B[^B]*W+[^B]*B");
                
if (reg.IsMatch(StrRoad))
                {
                    Console.WriteLine(
"您输入的序列有误,不允许两个黑之间出现白色。");
                    
continue;
                }
                Cur 
= StrRoad.IndexOf('F');
                
if (Cur == -1)
                {
                    Console.WriteLine(
"您输入的序列不包含青蛙F,请重新输入。");
                    
continue;
                }
                Console.WriteLine(
"首先开始正序尝试");
                
do
                {
                    Console.WriteLine(
"当前青蛙位置:" + (Cur + 1));
                    Swap(
ref StrRoad, Cur, Cur + 2);
                    
if (reg.IsMatch(StrRoad) || Cur + 2 > StrRoad.Length)
                    {
                        Swap(
ref StrRoad, Cur + 2, Cur);
                        Swap(
ref StrRoad, Cur, Cur + 1);
                        
if (reg.IsMatch(StrRoad))
                        {
                            Console.WriteLine(
"正序尝试失败。");
                            CountL 
= -1;
                            
break;
                        }
                        
else
                        {
                            Cur
++;
                            CountL
++;
                            Console.WriteLine(
"青蛙往前走了一步,进入了:" + (Cur + 1));
                        }
                    }
                    
else
                    {
                        Cur 
+= 2;
                        CountL
++;
                        Console.WriteLine(
"青蛙往前跳了一步,进入了:" + (Cur + 1));
                    }
                }
                
while (Cur < StrRoad.Length);
                
if (CountL != -1)
                {
                    Console.WriteLine(
"正序尝试成功,步数为" + CountL.ToString());
                }
                Console.WriteLine(
"下面考虑倒序。");
                StrRoad 
= ResvStrRoad;
                Cur 
= StrRoad.IndexOf('F');
                
do
                {
                    Console.WriteLine(
"当前青蛙位置:" + (StrRoad.Length - Cur).ToString());
                    Swap(
ref StrRoad, Cur, Cur + 2);
                    
if (reg.IsMatch(StrRoad) || Cur + 2 > StrRoad.Length)
                    {
                        Swap(
ref StrRoad, Cur + 2, Cur);
                        Swap(
ref StrRoad, Cur, Cur + 1);
                        
if (reg.IsMatch(StrRoad))
                        {
                            Console.WriteLine(
"倒序尝试失败。");
                            CountR 
= -1;
                            
break;
                        }
                        
else
                        {
                            Cur
++;
                            CountR
++;
                            Console.WriteLine(
"青蛙往前走了一步,进入了:" + (StrRoad.Length - Cur).ToString());
                        }
                    }
                    
else
                    {
                        Cur 
+= 2;
                        CountR
++;
                        Console.WriteLine(
"青蛙往前跳了一步,进入了:" + (StrRoad.Length - Cur).ToString());
                    }
                }
                
while (Cur < StrRoad.Length);
                
if (CountR == -1)
                {
                    Console.WriteLine(
"最终青蛙无法离开。");
                }
                
else
                {
                    Console.WriteLine(
"倒序尝试成功,步数为:" + CountR.ToString());
                    Console.WriteLine(
"综上考虑,两种序列,最优解为:" + (CountL < CountR ? CountL : CountR).ToString());
                }
            }
        }

        
static void Swap(ref string s, int pos, int newpos)
        {
            
if (pos >= s.Length || newpos >= s.Length)
                
return;
            StringBuilder sb 
= new StringBuilder(s);
            
char c = sb[pos];
            sb[pos] 
= sb[newpos];
            sb[newpos] 
= c;
            s 
= sb.ToString();
        }

        
static string Reverse(string text)
        {
            
char[] charArray = text.ToCharArray();
            Array.Reverse(charArray);
            
return new string(charArray);
        }
    }

 

 

posted on 2010-06-21 20:09  寻雨  阅读(580)  评论(0编辑  收藏  举报

导航