uva 1589 by sixleaves
坑爹的模拟题目。自己对于这种比较复杂点得模拟题的能力概述还不够,还多加练习。贴别是做得时候一直再想如何检查车中间有没有棋子,炮中间有没有棋子。到网上参考别人的代码才发先这么简单的办法,自己尽然想不到。多加练习,总结下该题目吧。
1 #include <stdio.h>
2 #include <string.h>
3 #define N 12
4
5 char brd[N][N];
6 int dx[] = {1,-1,0,0}, dy[] = {0,0,1,-1};
7 int hx[] = {-2,-1,-2,-1,1,2,1,2};
8 int hy[] = {-1,-2,1,2,-2,-1,2,1};
9 int tx[] = {-1,-1,-1,-1,1,1,1,1};
10 int ty[] = {-1,-1,1,1,-1,-1,1,1};
11 int cr[2], cc[2];
12
13
14 int check(int, int);
15
16 int main() {
17
18 int t, bX, bY;
19 char s[5];
20 while (scanf("%d%d%d",&t, &bX, &bY), t || bX || bY) {
21
22 memset(brd, 0, sizeof(brd));
23 cr[0] = cc[0] = cr[1] = cc[1] = 0;
24
25 for (int i = 0; i < t; i++) {
26
27 int rX, rY;
28 scanf("%s%d%d", s, &rX, &rY);
29 if ('C' == s[0]) {
30
31 if (cr[0]) cr[1] = rX, cc[1] = rY;
32 else cr[0] = rX, cc[0] = rY;
33 }
34 brd[rX][rY] = s[0];
35 }
36
37 // 判断是否四个方向都会被将军,或者无路可走的方向也认为是被将军
38 int cnt = 0;
39 for (int i = 0; i < 4; i++)
40 cnt += check(bX + dx[i], bY + dy[i]);
41
42 if (cnt < 4) puts("NO");
43 else puts("YES");
44
45 }
46
47 }
48
49 int check(int r, int c) {
50
51 // 越界,无路可走
52 if (r < 1 || r > 3 || c < 4 || c > 6) return 1;
53
54
55 // 因为我们没法保证车中间有没有其他棋子,所以必须从近到远一格格检查
56 // 车在同行且中间无棋子
57 for (int j = c - 1; j > 0; j--) {
58 if (brd[r][j])
59 if ('R' == brd[r][j]) return 1;
60 else break;
61 }
62
63 for (int j = c + 1; j <= 9; j++) {
64
65 if (brd[r][j])
66 if ('R' == brd[r][j]) return 1;
67 else break;
68 }
69
70
71 // 车在同列且中间物棋子
72 for (int j = r - 1; j > 0; j--) {
73
74 if (brd[j][c])
75 if ('R' == brd[j][c]) return 1;
76 else break;
77
78 }
79
80 for (int j = r + 1; j <=10; j++) {
81
82 if (brd[j][c])
83 if ('R' == brd[j][c] || 'G' == brd[j][c]) return 1;
84 else break;
85
86 }
87
88 // 炮将军
89 for (int k = 0; k < 2; k++) {
90
91 // 行有炮
92 if (r == cr[k]) {
93 int cnt = 0;
94 for (int j = c - 1; j > cc[k]; j--) if (brd[r][j]) ++cnt;
95 if (cnt == 1) return 1;
96 cnt = 0;
97 for (int j = c + 1; j < cc[k]; j++) if (brd[r][j]) ++cnt;
98 if (cnt == 1) return 1;
99
100 }
101
102 // 列有跑
103 if (c == cc[k]) {
104 int cnt = 0;
105 for (int j = r - 1; j > cr[k]; j--) if (brd[j][c]) ++cnt;
106 if (cnt == 1) return 1;
107 cnt = 0;
108 for (int j = r + 1; j < cr[k]; j++) if (brd[j][c]) ++cnt;
109 if (cnt == 1) return 1;
110 }
111
112
113 }
114
115 // 马将军,马的8个方位
116 for(int k = 0; k < 8; ++k) {
117
118 int tr = r + hx[k], tc = c + hy[k];
119 if (tr < 1 || tr > 10 || tc < 1 || tc > 9) continue;
120 if (brd[tr][tc] == 'H' && (!brd[r + tx[k]][c + ty[k]]))
121 return 1;
122
123 }
124 return 0;
125 }
2 #include <string.h>
3 #define N 12
4
5 char brd[N][N];
6 int dx[] = {1,-1,0,0}, dy[] = {0,0,1,-1};
7 int hx[] = {-2,-1,-2,-1,1,2,1,2};
8 int hy[] = {-1,-2,1,2,-2,-1,2,1};
9 int tx[] = {-1,-1,-1,-1,1,1,1,1};
10 int ty[] = {-1,-1,1,1,-1,-1,1,1};
11 int cr[2], cc[2];
12
13
14 int check(int, int);
15
16 int main() {
17
18 int t, bX, bY;
19 char s[5];
20 while (scanf("%d%d%d",&t, &bX, &bY), t || bX || bY) {
21
22 memset(brd, 0, sizeof(brd));
23 cr[0] = cc[0] = cr[1] = cc[1] = 0;
24
25 for (int i = 0; i < t; i++) {
26
27 int rX, rY;
28 scanf("%s%d%d", s, &rX, &rY);
29 if ('C' == s[0]) {
30
31 if (cr[0]) cr[1] = rX, cc[1] = rY;
32 else cr[0] = rX, cc[0] = rY;
33 }
34 brd[rX][rY] = s[0];
35 }
36
37 // 判断是否四个方向都会被将军,或者无路可走的方向也认为是被将军
38 int cnt = 0;
39 for (int i = 0; i < 4; i++)
40 cnt += check(bX + dx[i], bY + dy[i]);
41
42 if (cnt < 4) puts("NO");
43 else puts("YES");
44
45 }
46
47 }
48
49 int check(int r, int c) {
50
51 // 越界,无路可走
52 if (r < 1 || r > 3 || c < 4 || c > 6) return 1;
53
54
55 // 因为我们没法保证车中间有没有其他棋子,所以必须从近到远一格格检查
56 // 车在同行且中间无棋子
57 for (int j = c - 1; j > 0; j--) {
58 if (brd[r][j])
59 if ('R' == brd[r][j]) return 1;
60 else break;
61 }
62
63 for (int j = c + 1; j <= 9; j++) {
64
65 if (brd[r][j])
66 if ('R' == brd[r][j]) return 1;
67 else break;
68 }
69
70
71 // 车在同列且中间物棋子
72 for (int j = r - 1; j > 0; j--) {
73
74 if (brd[j][c])
75 if ('R' == brd[j][c]) return 1;
76 else break;
77
78 }
79
80 for (int j = r + 1; j <=10; j++) {
81
82 if (brd[j][c])
83 if ('R' == brd[j][c] || 'G' == brd[j][c]) return 1;
84 else break;
85
86 }
87
88 // 炮将军
89 for (int k = 0; k < 2; k++) {
90
91 // 行有炮
92 if (r == cr[k]) {
93 int cnt = 0;
94 for (int j = c - 1; j > cc[k]; j--) if (brd[r][j]) ++cnt;
95 if (cnt == 1) return 1;
96 cnt = 0;
97 for (int j = c + 1; j < cc[k]; j++) if (brd[r][j]) ++cnt;
98 if (cnt == 1) return 1;
99
100 }
101
102 // 列有跑
103 if (c == cc[k]) {
104 int cnt = 0;
105 for (int j = r - 1; j > cr[k]; j--) if (brd[j][c]) ++cnt;
106 if (cnt == 1) return 1;
107 cnt = 0;
108 for (int j = r + 1; j < cr[k]; j++) if (brd[j][c]) ++cnt;
109 if (cnt == 1) return 1;
110 }
111
112
113 }
114
115 // 马将军,马的8个方位
116 for(int k = 0; k < 8; ++k) {
117
118 int tr = r + hx[k], tc = c + hy[k];
119 if (tr < 1 || tr > 10 || tc < 1 || tc > 9) continue;
120 if (brd[tr][tc] == 'H' && (!brd[r + tx[k]][c + ty[k]]))
121 return 1;
122
123 }
124 return 0;
125 }
重剑无锋, 大巧不工。