题解:Puzzle(网格谜题)-UVA 227

题面:

  Vjudge UVA-227

  (题面是真的长,留个网址得了)😋

大意:

  有一个5×5的网格,其中恰好有一个格子是空的,其他格子各有一个字母。一共有4种指令:A,B,L,R,分别表示将空格上、下、左、右的相邻字母移到空格中。多组样例输入,每组输入一个5*5的表格和指令的字符串,指令以0结束。输出由指令变换后的5*5表格,如有非法输出,则输出This puzzle has no final configuration.

思路:

  很简单的模拟,只是有一堆输入输出的坑🤬

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main() {
 4     int kase = 0;
 5     while (1) {
 6         bool eal = 1;
 7         char s[5][5];
 8         int x, y;
 9         fgets(s[0], 7, stdin);                                //采用fgets来输入是这道题的一个特点,楼下细嗦 
10         if (s[0][0] == 'Z')return 0;
11         for (int i = 1; i < 5; i++) {
12             fgets(s[i], 7, stdin);
13         }
14         for (int i = 0; i < 5; i++) {                        //找空格 
15             for (int j = 0; j < 5; j++) {
16                 if (s[i][j] == ' ') {
17                     x = i;
18                     y = j;
19                 }
20             }
21         }
22         char move[105] = {0};
23         int cnt = 0;
24         char in;
25         while (cin >> in && in != '0')move[cnt++] = in;        //为防止指令有换行等采用这种指令的输入法 
26         for (int i = 0; i < cnt; ++i) {
27             switch (move[i]) {                                //模拟指令变换 
28                 case 'A':
29                     swap(s[x][y], s[x - 1][y]);
30                     x--;
31                     break;
32                 case 'B':
33                     swap(s[x][y], s[x + 1][y]);
34                     x++;
35                     break;
36                 case 'R':
37                     swap(s[x][y], s[x][y + 1]);
38                     y++;
39                     break;
40                 case 'L':
41                     swap(s[x][y], s[x][y - 1]);
42                     y--;
43                     break;
44                 default:
45                     break;
46             }
47             if (x < 0 || y < 0 || x > 4 || y > 4) {            //异常情况(越界) 
48                 eal = 0;                                    //对应下面的异常情况输出 
49                 break;
50             }
51         }
52         if (kase++)cout << endl;                            //永远在输出换行上坑人 
53         cout << "Puzzle #" << kase << ":\n";
54         if (eal) {
55             for (int i = 0; i < 5; i++) {
56                 for (int j = 0; j < 4; j++) {
57                     cout << s[i][j] << ' ';
58                 }
59                 cout << s[i][4] << endl;
60             }
61         } else {
62             cout << "This puzzle has no final configuration." << endl;
63         }
64         getchar();                                            //越狱丁真,鉴定为挖坑 
65     }
66 }
CanCanWord

后记:

  坑是真不少,下面细嗦:

  首先是犯了傲慢之罪的fgets(),由于本题的输入要求对空格,换行十分敏感,采用传统输入的scanf是无法做到所谓找空格,整行输入之类的,而采用gets又有各种缓冲区内存的漏洞,因此采用我从没用过的fgets。

  fgets的用法是fgets(buf,maxn,fin),buf是数组声明,max则是指要输入的字符个数,并且换行也算一个字符,换行还得是这一行的结尾,也就是要说的可以计入空格的整行输入的方法。

  然后是犯下愤怒之罪的getchar(),在输入指令的结束指示符0后,指令输入便告一段落,于是在敲击0后敲击的回车便合乎常理的填进了什么都吃的fgets()的肚子里😅,导致下一个表格输入错了一行。于是要用个getchar()在fgets()前抢先吃下换行。

  接着是犯下懒惰之罪的指令输入,为什么这玩意还要换行输入,只能用相对麻烦一些的间接输入了。

  再然后是犯下了嫉妒之罪的换行输出格式,实在是令人郁闷,对着英文题面扣了半天,得知它的输出是:

  input1......

  output1......

  input2......

 

  output2......

  input3.......

 

  output3......

  ......

  也就是除了第一个和最后一个样例外,其他的样例中输入输出中间要空一行......

  愤怒🤬愤怒🤬

 

  总结来说,思路简单,但真麻烦,对于我这样的新手来说😥

 

posted on 2022-08-11 18:59  Project_163  阅读(197)  评论(0)    收藏  举报

导航