UCF Local Programming Contest 2017 D. Editor Navigation【BFS,注意細節】

題目鏈接:https://nanti.jisuanke.com/t/44820

You are using a very simple text editor to create a document. You have typed in several lines, with the flashing cursor advancing as you type, but then you see a mistake on a previous line. Unfortunately, the mouse doesn’t work! You will have to press arrow keys to move the cursor back to the position where you can fix the mistake. Of course, you want to get to this position as quickly as possible.

在這裏插入圖片描述

This simple editor uses a monospace font, so each character is exactly the same width. The cursor can be at the beginning of the line (before the first character), end of the line (after the last character), or at a horizontal position between two characters on a given line. The following keys can be pressed to move the cursor (each keypress is independent of any preceding keypress):

在這裏插入圖片描述
在這裏插入圖片描述

The Problem:

Given the line lengths of a text file that was loaded in this simple editor, along with the current cursor position and a different, desired cursor position (e.g., to fix a mistake), you are to determine the minimum number of keypresses, using arrow keys only, required to move the cursor to the desired position.

The Input:

The first input line contains a positive integer, n, indicating the number of editor navigation scenarios to process. Each scenario will occupy exactly 4 input lines. The first line of each scenario contains an integer f (1 ≤ f ≤ 120), indicating the number of lines of text in the file that is loaded in the editor. The next input line contains f integers, s1 to sf, where each value si (0 ≤ si ≤ 80) indicates the number of characters on line i of the file; the values will be separated by exactly one space. A value si = 0 means that there are no characters on line i. The newline character (common character indicating end of a line) does not count as a character on the line. The third input line of each scenario will contain two integers (separated by a space) providing the current cursor position in the file: rc (1 ≤ rc ≤ f) and cc (0 ≤ cc ≤ 80), where rc represents the line of the file, counting from 1 (as with i), and cc represents the horizontal position of the cursor on that line, 0 for the beginning (before the first character). It is guaranteed that the cursor position is valid, so if, for instance, rc = 17 and s17 = 56, then 0 ≤ cc ≤ 56; the maximum value of cc is the end of the line. The fourth input line of each scenario is similar to the third and indicates the desired cursor position to begin fixing the mistake, i.e., this line consists of two integers separated by a space, rm (1 ≤ rm ≤ f) and cm (0 ≤ cm ≤ 80). The constraints on the values for rc and cc also apply to rm and cm.

The Output:

For each scenario in the input, output a single integer on a line by itself indicating the minimum number of keypresses needed to move the cursor from its current position (rc, cc) to the desired position (rm, cm) for fixing the mistake.

樣例輸入
2
7
39 20 57 54 14 38 31
7 31
3 39
3
15 30 20
1 12
3 3
樣例輸出
21
8
樣例解釋
For Case #1, one possible sequence for the minimum number of keypresses to move the cursor from its current position to the desired position is: Up, Up, Right, Up, Left, Up, Left 15 times.

收穫(教訓)

這題其實不算難,基本上就是裸的BFS,主要是細節上有很多要注意的地方。

  1. 兩個if代碼塊中均存在的變量名不要重複使用,因爲可能會把變量修改了,對下一個if語句的判斷會有影響(debug的時候發現一次BFS似乎連續走了兩個點)
  2. 還是要注意讀題,這題與普通BFS不同的地方就在於上下移動時可能改變列下標,左右移動時也可能改變行下標(在一行的最左邊再左移,將跳到上一行的末尾)。
  3. 注意方向,x-1是向上走(注意這個圖的座標不是按平面直角座標系畫的)
  4. 當起點在下方,終點在上方時,垂直方向不應該限定只能往上走,因爲這題在垂直方向走可能把列下標改變很多,從而得到最優解。

AC代碼

#include <bits/stdc++.h>
using namespace std;
const int N=125,M=85;
int T,n,bx,by,ex,ey,num[N];
bool vis[N][M];
int dir[4][2]={-1,0,1,0,0,-1,0,1};//上、下、左、右(注意向上走是x-1)
struct node
{
    int x,y,cnt;
};
void bfs()
{
    queue<node>q;
    q.push({bx,by,0});
    memset(vis,0,sizeof(vis));
    vis[bx][by]=1;
    while(!q.empty())
    {
        node tmp=q.front();q.pop();
        int x=tmp.x;
        int y=tmp.y;
        int cnt=tmp.cnt;
        //printf("x=%d y=%d cnt=%d\n",x,y,cnt);
        if(x==ex&&y==ey){printf("%d\n",cnt);return;}
        for(int i=0;i<4;i++)
        {
            int nx=x+dir[i][0];
            int ny=y+dir[i][1];
            if(nx>=1&&nx<=n)
            {
                if(i==0||i==1)//上下移動
                {
                    if(ny<=num[nx]&&!vis[nx][ny])//在長度範圍內,直走
                    {
                        vis[nx][ny]=1;
                        q.push({nx,ny,cnt+1});
                    }
                    if(ny>num[nx]&&!vis[nx][num[nx]])//長->短
                    {
                        vis[nx][num[nx]]=1;
                        q.push({nx,num[nx],cnt+1});
                    }
                }
                else//左右移動 i=2左移 i=3右移
                {
                    if(ny==-1&&i==2&&x-1>=1)//左移到開頭前一個,則跳轉到上層最後一個
                    {
                        int tx=x-1;//注意一定要換個變量,別用nx了,否則後面可能還會改變這個變量
                        int ty=num[tx];
                        if(!vis[tx][ty])
                        {
                            vis[tx][ty]=1;
                            q.push({tx,ty,cnt+1});
                        }
                    }
                    if(ny==num[x]+1&&i==3&&x+1<=n)//右移到行尾後一個,則跳轉到下層第一個
                    {
                        int tx=x+1;
                        int ty=0;
                        if(!vis[tx][ty])
                        {
                            vis[tx][ty]=1;
                            q.push({tx,ty,cnt+1});
                        }
                    }
                    if(ny>=0&&ny<=num[x]&&!vis[x][ny])//本行內左右移動
                    {
                        vis[x][ny]=1;
                        q.push({x,ny,cnt+1});
                    }
                }
            }
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>num[i];
        cin>>bx>>by>>ex>>ey;
        bfs();
    }
    return 0;
}
/*
1
3
15 30 20
1 12
3 3
ans:8

1
2
1 1
1 0
2 1
ans:2

1
4
1 2 3 4
1 0
4 3
ans:5
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章