`
utensil
  • 浏览: 152421 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Google Code Jam之Always Turn Left之我的解答

阅读更多
由于时间的限制,程序有些地方的容错性不够,以//!! 标出。
运行成功,经Google Code Jam鉴定为正确。
 
题目为:
 
Always Turn Left

Problem

You find yourself standing outside of a perfect maze. A maze is defined as "perfect" if it meets the following conditions:

  1. It is a rectangular grid of rooms, R rows by C columns.
  2. There are exactly two openings on the outside of the maze: the entrance and the exit. The entrance is always on the north wall, while the exit could be on any wall.
  3. There is exactly one path between any two rooms in the maze (that is, exactly one path that does not involve backtracking).

You decide to solve the perfect maze using the "always turn left" algorithm, which states that you take the leftmost fork at every opportunity. If you hit a dead end, you turn right twice (180 degrees clockwise) and continue. (If you were to stick out your left arm and touch the wall while following this algorithm, you'd solve the maze without ever breaking contact with the wall.) Once you finish the maze, you decide to go the extra step and solve it again (still always turning left), but starting at the exit and finishing at the entrance.

The path you take through the maze can be described with three characters: 'W' means to walk forward into the next room, 'L' means to turn left (or counterclockwise) 90 degrees, and 'R' means to turn right (or clockwise) 90 degrees. You begin outside the maze, immediately adjacent to the entrance, facing the maze. You finish when you have stepped outside the maze through the exit. For example, if the entrance is on the north and the exit is on the west, your path through the following maze would be WRWWLWWLWWLWLWRRWRWWWRWWRWLW :

If the entrance and exit were reversed such that you began outside the west wall and finished out the north wall, your path would be WWRRWLWLWWLWWLWWRWWRWWLW . Given your two paths through the maze (entrance to exit and exit to entrance), your code should return a description of the maze.

Input

The first line of input gives the number of cases, N . N test cases follow. Each case is a line formatted as

entrance_to_exit exit_to_entrance

All paths will be at least two characters long, consist only of the characters 'W', 'L', and 'R', and begin and end with 'W'.

Output

For each test case, output one line containing "Case #x :" by itself. The next R lines give a description of the R by C maze. There should be C characters in each line, representing which directions it is possible to walk from that room. Refer to the following legend:

Character   Can walk north?   Can walk south?   Can walk west?   Can walk east?  
1 Yes No No No
2 No Yes No No
3 Yes Yes No No
4 No No Yes No
5 Yes No Yes No
6 No Yes Yes No
7 Yes Yes Yes No
8 No No No Yes
9 Yes No No Yes
a No Yes No Yes
b Yes Yes No Yes
c No No Yes Yes
d Yes No Yes Yes
e No Yes Yes Yes
f Yes Yes Yes Yes

Limits

1 ≤ N ≤ 100.

Small dataset

2 ≤ len(entrance_to_exit) ≤ 100, 2 ≤ len(exit_to_entrance) ≤ 100.

Large dataset

2 ≤ len(entrance_to_exit) ≤ 10000, 2 ≤ len(exit_to_entrance) ≤ 10000.

Sample

Input
2 WRWWLWWLWWLWLWRRWRWWWRWWRWLW WWRRWLWLWWLWWLWWRWWRWWLW WW WW
Output
Case #1: ac5 386 9c7 e43 9c5 Case #2: 3
 
我的解答为:
 

 

#include <iostream>

#include <fstream>

#include <map>

#include <iomanip>

//#define MY_DEBUG

using namespace std;

 

 

/*

    +----------->i

    |

    |

    |

    V

    j

*/

struct maze_coord

{

    maze_coord()

    {

        i = j = 0;

    }

    maze_coord(int i_, int j_)

    {

        i = i_;

        j = j_;

    }

    int i;

    int j;

 

    //for being put into map

    bool operator < (const maze_coord& other) const

    {

        return (j < other.j) || (j == other.j && i < other.i);

    }

 

    //for calculating the size of the maze

    maze_coord operator - (const maze_coord& other) const

    {

        return maze_coord(i - other.i, j - other.j);

    }

};

 

enum direction

{

    north = 1,

    south = 1<<1,

    west = 1<<2,

    east = 1<<3

};

 

#ifdef MY_DEBUG

//direction symbol

const char* symbol = " ^V <   >";

#endif

 

//clockwise cycle

const direction cycle[4] = {north, east, south, west};

 

//helper function to turn the direction

//turn for |n|*90 degrees

//n<0 to turn left

//n>0 to turn right

direction turn(direction d, int n = 1)

{

    for(int i = 0; i < 4; i++)

    {

        if(cycle[i] == d)

        {

            i = (i+n)%4;

            return cycle[(i>=0)?i:(4+i)];

        }

    }

}

 

// high 4 bits are used to mark known/unknown status

// low 4 bits are used to mark can/cant walk status

// order:

// east west south north

typedef unsigned char room_state;

 

typedef map<maze_coord, room_state> Maze;

 

//Rat will walk in the maze, and mark the state of every room

class Rat

{

    public:

        Rat(Maze& maze)

        :m_maze(maze)

        {

            m_heading = south;

            m_coord.i = 0;

            m_coord.j = -1;

        }

 

        //W

        void Walk(bool is_next_step_walk)

        {

            //If there is record for the last room

            //Mark it as walkable

            if(m_maze.count(m_coord))

            {

                m_maze[m_coord] |= m_heading;

                m_maze[m_coord] |= m_heading<<4;

            }

 

            //Walk

            switch(m_heading)

            {

                case north : --m_coord.j;break;

                case south : ++m_coord.j;break;

                case west : --m_coord.i;break;

                case east : ++m_coord.i;break;

            }

 

            //If there is no record for the current room

            //Clear its state

            if(!m_maze.count(m_coord))

                m_maze[m_coord] = 0x00;

 

            direction walkable_wall = turn(m_heading, 2);

            m_maze[m_coord] |= walkable_wall; //it's walkable

            m_maze[m_coord] |= walkable_wall<<4; //it's known

 

            //WW

            if(is_next_step_walk)

            {

                //left

                direction unwalkable_wall = turn(m_heading, -1);

                m_maze[m_coord] |= unwalkable_wall<<4; //it's known to be unwalkable

            }

 

            #ifdef MY_DEBUG

            cout << "Walk to ";

            cout << dec << '(' << m_coord.i << ',' << m_coord.j << ')' << '';

            cout << "Heading "<< symbol[m_heading] << ":";

            cout << hex << (unsigned int)m_maze[m_coord] << endl;

            #endif

        }

 

        //L

        void TurnLeft()

        {

            //turn left

            m_heading = turn(m_heading, -1);

 

            //left

            m_maze[m_coord] |= m_heading; //it's walkable

            m_maze[m_coord] |= m_heading<<4; //it's known

 

            #ifdef MY_DEBUG

            cout << "Turn left " << '';

            cout << "Heading "<< symbol[m_heading] << ":";

            cout << hex << (unsigned int)m_maze[m_coord] << endl;

            #endif

        }

 

        //R

        void TurnRight()

        {

            //left

            direction unwalkable_wall = turn(m_heading, -1);

            m_maze[m_coord] |= unwalkable_wall<<4; //it's known to be unwalkable

 

            //forward

            unwalkable_wall = m_heading;

            m_maze[m_coord] |= unwalkable_wall<<4; //it's known to be unwalkable

 

            //right

            m_heading = turn(m_heading, 1); //turn right

            m_maze[m_coord] |= m_heading; //it's walkable

            m_maze[m_coord] |= m_heading<<4; //it's known

 

            #ifdef MY_DEBUG

            cout << "Turn right " << '';

            cout << "Heading "<< symbol[m_heading] << ":";

            cout << hex << (unsigned int)m_maze[m_coord] << endl;

            #endif

        }

 

        //RR

        void TurnBack()

        {

            //left

            direction unwalkable_wall = turn(m_heading, -1);

            m_maze[m_coord] |= unwalkable_wall<<4; //it's known to be unwalkable

 

            //forward

            unwalkable_wall = m_heading;

            m_maze[m_coord] |= unwalkable_wall<<4; //it's known to be unwalkable

 

            //right

            unwalkable_wall = turn(m_heading, 1);

            m_maze[m_coord] |= unwalkable_wall<<4; //it's known to be unwalkable

 

            //turn back

            m_heading = turn(m_heading, 2);

 

            #ifdef MY_DEBUG

            cout << "Turn back " << '';

            cout << "Heading "<< symbol[m_heading] << ":";

            cout << hex << (unsigned int)m_maze[m_coord] << endl;

            #endif

        }

 

        //Clear the record for current room

        //call it after gets out of the exit and TurnBack

        void ClearCurrentRoom()

        {

            m_maze.erase(m_coord);

 

            #ifdef MY_DEBUG

            cout << "+++++++++++++" << endl;

            #endif

        }

 

        //for speeding up the programming, break the encapsulation a little

        direction m_heading;

        maze_coord m_coord;

        Maze& m_maze;

};

 

int main(int argc, char* argv[])

{

    #ifndef MY_DEBUG

    //Only for memerizing usage for myself

    if(argc != 3)

    {

        cout << "Usage: atl INPUT_FILE OUTPUT_FILE" << endl;

        return 0;

    }

 

    ifstream fin(argv[1]); //!!

    ofstream fout(argv[2]); //!!

    #else

    ifstream fin("B-large.in"); //!!

    ofstream fout("test.out"); //!!

    #endif

 

    //How many cases in total?

    int case_max;

    fin >> case_max;

    fin.ignore(); // ''

 

    char tmp;

 

    for(int cur_case = 1; cur_case <= case_max; cur_case++)

    {

        Maze maze;

        Rat rat(maze);

 

        while((tmp = fin.get()) != '')//!!

        {

            switch(tmp)

            {

                case 'W' :

                rat.Walk(fin.peek() == 'W');

                break;

                case 'L' : rat.TurnLeft(); break;

                case 'R' :

                    if(fin.get() == 'R') rat.TurnBack();

                    else

                    {

                        fin.unget();

                        rat.TurnRight();

                    }

                    break;

                case ' ' ://!!

                    rat.TurnBack();

                    rat.ClearCurrentRoom();

                    break;

            }

 

        }

        rat.ClearCurrentRoom();

 

        maze_coord top_left = maze.begin()->first;

        maze_coord bottom_right = (--maze.end())->first;

 

        //This style works, but I guess it's slower

        #if 0

            fout << "Case #" << dec << cur_case << ':' << endl;

 

            for(int row = top_left.j; row <= bottom_right.j; row++)

            {

                for(int col = top_left.i; col <= bottom_right.i; col++)

                {

                    fout << hex << (unsigned int)(0x0f&maze[maze_coord(col, row)]);

                }

                fout << endl;

            }

        #endif

 

        //Start writing the file

        fout << "Case #" << dec << cur_case << ':' << endl;

 

        //in non-debug mode, show the progress

        #ifndef MY_DEBUG

        cout << "Case #" << dec << cur_case << endl;

        #endif

 

        int max_col = (bottom_right - top_left).i;

        int cur_col = 0;

 

        for(Maze::iterator it = maze.begin(); it != maze.end(); ++it)

        {

            #ifdef MY_DEBUG

            cout << hex << (unsigned int)(*it).second << ' ';

            #endif

 

            fout << hex << (unsigned int)(0x0f&(*it).second);

            if(cur_col == max_col)

            {

                fout << endl;

                #ifdef MY_DEBUG

                cout << endl;

                #endif

                cur_col = 0;

                continue;

            }

            ++cur_col;

        }

    }

 

    return 0;

}
分享到:
评论

相关推荐

    Google_code_jam.rar_Google jam_google code jam_google code jam j

    Google Code Jam是谷歌举办的一项全球性的编程竞赛,旨在挑战参赛者的算法设计和问题解决能力。这个压缩包"Google_code_jam.rar"包含了某位参赛者对Google Code Jam比赛中的问题的解决方案。从标签"google_jam"、...

    google code jam

    google code jam

    google codejam2014

    google codejam2014源代码

    Google code jam - World Finals 2017-Problem A. Dice Straight

    抱歉,CSDN目前无法设置免费资源,感兴趣的话在我博客下留言,我可以用邮件发给你。 Small input of Google code jam - World Finals 2017-Problem A. Dice Straight

    GCJ.rar_code jam_google code jam

    《GCJ.rar_code jam_google code jam》是2008年Google Code Jam第三轮网络竞赛的编程代码资源,其中包含了lym和windy两位顶尖程序员的解决方案。这个压缩包是编程爱好者和参赛者宝贵的参考资料,它揭示了在解决算法...

    google code jam Qualification Round 2011题解 参考源码

    自己写的源码,希望各位看官指出不足之处,好交流进步

    google_codejam:Google Codejam挑战的代码

    【Google Codejam:全球顶尖编程挑战的深度剖析】 Google Codejam是谷歌主办的一项年度国际级编程竞赛,旨在挑战参赛者解决复杂算法问题的能力。自2003年起,这个比赛吸引了世界各地的编程爱好者和专业人士参与,它...

    CodeJam:Google Code Jam 练习题的解决方案

    Google Code Jam 练习题的解决方案 在与给定问题具有相同标题的 java 类中找到解决方案。 在这一点上,所有解决方案都针对在明确提到的作为良好起点的问题 每个解决方案都需要从命令行运行一个参数,一个包含问题...

    google_codejam_stats:用于检查Google Code Jam轮次统计信息的网站

    Google Code Jam统计用于检查Google Code Jam轮次统计信息的网站为什么? 已经有一些很棒的网站(例如和 ),但它们仅提供截至2017年的数据。该网站使用于2018年推出的新Google Competitions API来收集并显示有关...

    GoogleCodeJam:我的Google Code Jam旅程

    我的Google Code Jam旅程记录我的GCJ旅程的回购。 每年更新。 年日期圆形的结果评论2020年5月2日1C2020年4月20日1B数学太多2020年4月11日1A2020年4月4日资质做得好2019年5月4日1C搞砸了2019年4月28日1B需要更多练习...

    code-jam:Google Code Jam 解决方案

    在Google Code Jam中,Java的强类型系统、面向对象特性以及丰富的数据结构和算法库使得它成为参赛者们解决复杂问题的首选工具之一。 在这个压缩包中,我们可以期待找到以下内容: 1. **源代码文件**:每个文件可能...

    codejam:解决Code Jam 2021及更早版本的问题的解决方案

    这个资料库包含我在2021年之前解决Google Code Jam竞赛问题的解决方案,无论是在竞赛期间提交还是经过深思熟虑。 源代码使用Java,每个源文件都包含对所用算法的描述。 src目录中的Java软件包包含按Code Jam版本和...

    8051 Jam Byte-Code Player

    README File for 8051 Jam Byte-Code Player v1.0 What Does v1.0 Support? The source code supports programming devices from the 8051 family of microprocessors. Jam Byte-Code (.jbc) files from the ...

    Codejam:我的 Google Codejam 解决方案

    《Google Codejam:JavaScript实战解析》 Google Codejam,一项全球知名的编程竞赛,吸引着无数程序员挑战自我,提升技能。本篇文章将深入探讨如何利用JavaScript解决Codejam中的问题,通过具体的实战案例,揭示...

    googlecodejam:我的Google Code Jam解决方案

    googlecodejam 我的Google Code Jam解决方案内容(比赛中的结果)-当前20 质量: Reversort(正确)-已解决月亮和雨伞(正确,正确,吗?)-已解决| 不是测试用例3 Reversort Engineering(正确,错误的答案)-特定...

    google-codejam-2015:我为 Google Code Jam 2015 所做的一切

    在本文中,我们将深入探讨与"Google Code Jam 2015"相关的编程挑战和解决方案,特别是使用Java语言。Google Code Jam是谷歌主办的一项全球性的编程竞赛,旨在测试参赛者解决算法问题的能力和编程技巧。2015年的比赛...

    google-code-jam-2018:我对Google Code Jam 2018问题的解决方案

    该存储库包含我针对和Distributed Google Code Jam 2018中的问题的解决方案。这些解决方案“按原样”提供-我不保证它们将按预期运行。 指示 您可以通过发出以下命令来编译所有Google Code Jam问题: $ make 如果...

    codejam比赛环境,方便快速进行比赛.zip

    Codejam比赛环境是Google举办的一项年度编程竞赛Google Code Jam的专用平台,旨在挑战全球程序员的算法和问题解决能力。为了方便参赛者快速进入比赛状态,这个压缩包提供了一个配置好的环境,包含了所有必要的工具和...

    google-codejam:我对Google Codejam的解决方案

    谷歌Codejam是一个全球知名的编程竞赛,由互联网巨头Google主办,旨在挑战参赛者解决算法和逻辑难题的能力。在本文中,我们将深入探讨如何使用C#语言来应对Google Codejam中的问题,以及解决这些问题的关键策略和...

    CodeJam2015:Google Code Jam 2015 解决方案

    【标题】"CodeJam2015:Google Code Jam 2015 解决方案" 涉及的是一场由谷歌主办的编程竞赛——Google Code Jam 2015。该竞赛旨在挑战参赛者在算法设计、问题解决以及编程方面的技能。参赛者需要解决一系列复杂的编程...

Global site tag (gtag.js) - Google Analytics