Programming thinking week2 homework

Programming thinking assignment week2

本次作业的两个题都是BFS的典型应用。

Problem A :Maze

1. Topic Overview

Dongdong has a map and wants to find the sister paper through the map. The map shows that 0 means you can walk, 1 means you can't walk, the upper left corner is the entrance, and the lower right corner is the sister paper. These two positions are guaranteed to be 0. Now that you know the map, it is not difficult for Dongdong to find sister paper. Please write a program to write the shortest route for Dongdong to find sister paper.

2.Input

The input is a 5 × 5 two-dimensional array, consisting of only two digits 0 and 1, representing a normal matrix map.

3.Output

Several lines are output, representing the coordinates of the shortest path from the upper left corner to the lower right corner, in the format shown in the sample. The data is guaranteed to have a unique solution.

4.Sample

sample input

0 1 0 0 0
0 1 0 1 0
0 1 0 1 0
0 0 0 1 0
0 1 0 1 0

sample output

(0, 0)
(1, 0)
(2, 0)
(3, 0)
(3, 1)
(3, 2)
(2, 2)
(1, 2)
(0, 2)
(0, 3)
(0, 4)
(1, 4)
(2, 4)
(3, 4)
(4, 4)

5. The overall idea

The idea is relatively simple, use the stack to simulate the BFS process, save the one that successfully reaches the end point on the stack, and then use the other stack to output in reverse order.

6. Code

#include<iostream>
#include<stack>
using namespace std;
//记录点的坐标
class point
{
public:
    point(int x,int y)
    {
        _x=x;
        _y=y;
    }
    void output()
    {
        cout<<'('<<_x-1<<','<<' '<<_y-1<<')'<<endl;
    }
public:
    int _x;
    int _y;

};

int _dx[]={1,0,0,-1};
int _dy[]={0,-1,1,0};
stack<point> track;
int a[7][7];
int main()
{
    //初始化
    for(int i=0;i<7;i++)
    {
        for(int j=0;j<7;j++)
        {
            if((i*j==0)||i==6||j==6)
                a[i][j]=1;
            else cin>>a[i][j];
        }
    }
    //输入起点
    point start(1,1);
    point terminate(5,5);
    track.push(start);
    //判断终点条件
    while(!(track.top()._x==5&&track.top()._y==5))
    {
        point now=track.top();
        a[now._x][now._y]=1;
        int i;
        //BFS过程
        for(i=0;i<4;i++)
        {
            int new_x=now._x+_dx[i];
            int new_y=now._y+_dy[i];
            if(a[new_x][new_y]!=1)
            {
                a[new_x][new_y]=1;
                track.push({new_x, new_y});
                break;
            }
        }
        if(i==4) track.pop();
    }
    int size=track.size();
    stack<point> newtrack;
    for(int k=0;k<size;k++)
    {
        point n(track.top()._x,track.top()._y);
        track.pop();
        newtrack.push(n);
    }
    for(int i=0;i<size;i++)
    {
        newtrack.top().output();
        newtrack.pop();
    }
    return 0;
}

Problem B :Pour Water

1. Topic Overview

Pour water problem "fill A" means to fill the A cup, "empty A" means to empty the A cup, "pour AB" means to pour A's water into the B cup and empty the B cup or A.

2. Sample inout and output

Input

The input contains multiple sets of data. Each group of data input A, B, C data range 0 <A <= B, C <= B <= 1000, A and B are relatively prime.

Sample Input
2 7 5
2 7 4

Output

The output of your program will consist of a series of instructions. These output lines will cause any tank to contain exactly C units of water. The output of the last line of each set of data should be "success". The output line starts at column 1, and there should be no blank lines or any trailing spaces.

Sample Output
fill B
pour B A
success 
fill A
pour A B
fill A
pour A B
success

3. The overall idea and code

This question is also the application of BFS. Replace the up-down, left-right movement expansion in problem A with the full, empty, and A (B) to B (A). Through the use of map can record the state of the previous state of a state. Then according to the difference between the two states to determine the specific operation in this step.

#include<iostream>
#include<queue>
#include<map>
using namespace std;

struct Status
{
    int a, b;
    bool operator<(const Status &s) const
    {
        return a!=s.a ? a<s.a : b<s.b;
    }
};

/* 递归输出方案 */
void print(Status &p,map<Status, Status> from)
{
    if ( from.find(p) == from.end())
    {
        //cout<<"success"<<endl;
        return ;
    }
    if(p.a == 0&&p.b==0)
    {
        return ;
    }
    print(from[p],from); // 递归
    int _a=from[p].a;
    int _b=from[p].b;
    if(p.a!=_a)
    {
        if(p.a>_a)
        {
            if(p.b<_b)
                cout<<"pour B A"<<endl;
            else
                cout<<"fill A"<<endl;
        } else{
            if(p.b>_b)
                cout<<"pour A B"<<endl;
            else
                cout<<"empty A"<<endl;
        }
    } else{
        //p.a==_a
        if(p.b>_b)
            cout<<"fill B"<<endl;
        else
            cout<<"empty B"<<endl;
    }
    //printf("-><%d,%d>",  p.a, p.b);
}

void refresh(Status &s, Status &t,map<Status, Status> &from,queue<Status> &Q)
{
    if ( from.find(t) == from.end() )
    { // 特判合法,加入队列
        from[t] = s;
        Q.push(t);
    }
}

void bfs(int A, int B, int C,map<Status, Status> from,queue<Status> &Q)
{
    // 起点, 两杯水都空
    Status s,t;
    s.a=0; s.b=0;
    Q.push(s);

    while (!Q.empty())
    {
        // 取队首
        s = Q.front();
        Q.pop();
        // 特判到达终点
        if (s.a == C || s.b == C) {
            print(s,from); // 输出方案
            return;
        }

        // 倒空 a 杯的水
        if (s.a > 0) {
            t.a = 0;  // 倒空
            t.b = s.b;// b 杯不变
            refresh(s, t,from,Q);
        }

        // 同理,倒空 b 杯的水
        if (s.b > 0) {
            t.b = 0;  // 倒空
            t.a = s.a;// a 杯不变
            refresh(s, t,from,Q);
        }

        // a 杯未满,续满 a 杯
        if (s.a < A)
        {
            // 续满 a 杯
            t.a = A;
            t.b = s.b;
            refresh(s, t,from,Q);

            // 考虑倒入
            if (s.b != 0)
            {
                if (s.a + s.b <= A)
                {
                    t.a = s.a + s.b;
                    t.b = 0;
                    refresh(s, t,from,Q);
                } else
                {
                    t.a = A;
                    t.b = s.a + s.b - A;
                    refresh(s, t,from,Q);
                }
            }
        }

        // 同理,b 杯未满,续满 b 杯
        if (s.b < B)
        {
            t.a = s.a;
            t.b = B;
            refresh(s, t,from,Q);
            if (s.a != 0)
            {
                if (s.a + s.b <= B)
                {
                    t.a = 0;
                    t.b = s.a + s.b;
                    refresh(s, t,from,Q);
                } else
                {
                    t.a = s.a + s.b - B;
                    t.b = B;
                    refresh(s, t,from,Q);
                }
            }
        }
    }
    printf("-1\n");
}
int main()
{
    int a;
    while (cin>>a) {
        queue<Status> Q;
        map<Status, Status> from;
        int b,c;
        cin>>b;
        cin>>c;
        bfs(a, b, c,from,Q);
        cout<<"success"<<endl;
    }
    return 0;
}
Published 8 original articles · Likes2 · Visits 252

Guess you like

Origin blog.csdn.net/lawrenceY/article/details/104688670