比赛笔试链接:http://hihocoder.com/contest/ntest2015april/problems
题目就不贴了。
1、推箱子。
思路:纯模拟。
代码(28MS):
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int MAXV = 10010; 5 6 const char str_op[] = "dulr"; 7 int fx[] = {1, -1, 0, 0}; 8 int fy[] = {0, 0, -1, 1}; 9 10 inline int id(char c) { 11 static const char op[] = "dulr"; 12 return strchr(op, c) - op; 13 } 14 15 char op[MAXV]; 16 int len; 17 char mat[105][105]; 18 int n, m, s; 19 20 int sx, sy, vx, vy, ex, ey; 21 22 void init() { 23 for(int i = 1; i <= n; ++i) 24 for(int j = 1; j <= m; ++j) { 25 if(mat[i][j] == '1') sx = i, sy = j; 26 if(mat[i][j] == '2') ex = i, ey = j; 27 if(mat[i][j] == '3') vx = i, vy = j; 28 } 29 } 30 31 bool solve() { 32 int x1 = sx, y1 = sy, x2 = vx, y2 = vy; 33 for(int i = 0; i < len; ++i) { 34 int f = id(op[i]); 35 int new_x = x1 + fx[f], new_y = y1 + fy[f]; 36 if(new_x == x2 && new_y == y2) { 37 int pp = x2 + fx[f], qq = y2 + fy[f]; 38 if(mat[pp][qq] != '4') { 39 x1 = new_x, y1 = new_y; 40 x2 = pp, y2 = qq; 41 } 42 } else if(mat[new_x][new_y] != '4') { 43 x1 = new_x, y1 = new_y; 44 } 45 if(x2 == ex && y2 == ey) return true; 46 } 47 return false; 48 } 49 50 int main() { 51 memset(mat, '4', sizeof(mat)); 52 scanf("%d%d%d", &m, &n, &s); 53 for(int i = 1; i <= n; ++i) 54 for(int j = 1; j <= m; ++j) scanf(" %c", &mat[i][j]); 55 init(); 56 while(s--) { 57 scanf("%d %s", &len, op); 58 puts(solve() ? "YES" : "NO"); 59 } 60 }
2、井字棋
思路:俗称井字过三关。题目没有提到的三种不合法情况:
①XO都有3连
②X有3连,但是count(X)=count(O)
③O有3连,但是count(X)-1=count(O)
其他不难。人工手动枚举大法好。简单粗暴不易出错。
不过我又成功在通过样例之前把代码交了上去导致WA20(不算罚时就是好啊)
代码(15MS):
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #include <iostream> 5 using namespace std; 6 typedef long long LL; 7 8 int f[8][3] = { 9 {0, 1, 2}, 10 {3, 4, 5}, 11 {6, 7, 8}, 12 {0, 3, 6}, 13 {1, 4, 7}, 14 {2, 5, 8}, 15 {0, 4, 8}, 16 {2, 4, 6} 17 }; 18 19 char mat[10]; 20 int wino[8], winx[8]; 21 int T; 22 23 void build_check(int win[], char c) { 24 for(int i = 0; i < 8; ++i) { 25 win[i] = 1; 26 for(int j = 0; j < 3; ++j) 27 if(mat[f[i][j]] != c) win[i] = 0; 28 } 29 } 30 31 int build_count(char c) { 32 return count(mat, mat + 9, c); 33 } 34 35 bool next_win(char c) { 36 int win[8]; 37 for(int i = 0; i < 9; ++i) if(mat[i] == '_') { 38 mat[i] = c; 39 build_check(win, c); 40 if(count(win, win + 8, 1)) return true; 41 mat[i] = '_'; 42 } 43 return false; 44 } 45 46 int solve() { 47 int xcnt = build_count('X'), ocnt = build_count('O'); 48 if(xcnt != ocnt && xcnt - 1 != ocnt) return puts("Invalid"); 49 50 build_check(winx, 'X'); 51 build_check(wino, 'O'); 52 if(count(winx, winx + 8, 1) > 0 && count(wino, wino + 8, 1) > 0) return puts("Invalid"); 53 if(count(winx, winx + 8, 1) > 0 && xcnt == ocnt) return puts("Invalid"); 54 if(count(wino, wino + 8, 1) > 0 && xcnt - 1 == ocnt) return puts("Invalid"); 55 56 if(count(winx, winx + 8, 1) > 0) return puts("X win"); 57 if(count(wino, wino + 8, 1) > 0) return puts("O win"); 58 59 if(build_count('_') == 0) return puts("Draw"); 60 61 if(next_win(xcnt == ocnt ? 'X' : 'O')) return puts("Next win"); 62 return puts("Next cannot win"); 63 } 64 65 int main() { 66 scanf("%d", &T); 67 while(T--) { 68 scanf("%s", mat); 69 scanf("%s", mat + 3); 70 scanf("%s", mat + 6); 71 solve(); 72 } 73 }
3、连连看
思路:参照最小转弯问题:http://www.cnblogs.com/oyking/p/3756208.html
估计直接来个heap+dijkstra也能100分把。
代码(302MS):
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <queue> 6 using namespace std; 7 8 const int MAXN = 210; 9 const int INF = 0x3f3f3f3f; 10 11 struct Node { 12 int f, x, y; 13 Node() {} 14 Node(int f, int x, int y): 15 f(f), x(x), y(y) {} 16 }; 17 18 int fx[] = {-1, 0, 1, 0}; 19 int fy[] = {0, 1, 0, -1}; 20 21 int dis[4][MAXN][MAXN]; 22 int mat[MAXN][MAXN]; 23 bool vis[MAXN][MAXN]; 24 int T, n, m; 25 26 int bfs(int x1, int y1, int k) { 27 memset(vis, 0, sizeof(vis)); vis[x1][y1] = true; 28 memset(dis, 0x3f, sizeof(dis)); 29 queue<Node> *now = new queue<Node>(); 30 queue<Node> *nxt = new queue<Node>(); 31 int step = 0, res = 0; 32 for(int i = 0; i < 4; ++i) now->push(Node(i, x1, y1)); 33 for(int i = 0; i < 4; ++i) dis[i][x1][y1] = 0; 34 while(step <= k && !now->empty()) { 35 Node t = now->front(); now->pop(); 36 if(dis[t.f][t.x][t.y] != step) continue; 37 for(int i = 0; i < 4; ++i) { 38 if((t.f + 2) % 4 == i) continue; 39 int x = t.x + fx[i], y = t.y + fy[i], d = dis[t.f][t.x][t.y] + (t.f != i); 40 if(mat[x][y] == mat[x1][y1] && !vis[x][y] && d <= k) { 41 vis[x][y] = true; 42 res++; 43 } 44 if(mat[x][y] == 0 && d < dis[i][x][y]) { 45 dis[i][x][y] = d; 46 if(t.f == i) now->push(Node(i, x, y)); 47 else nxt->push(Node(i, x, y)); 48 } 49 } 50 if(now->empty()) { 51 step++; 52 swap(now, nxt); 53 } 54 } 55 return res; 56 } 57 58 int main() { 59 scanf("%d", &T); 60 while(T--) { 61 scanf("%d%d", &n, &m); 62 memset(mat, 0x3f, sizeof(mat)); 63 for(int i = 2; i <= n + 1; ++i) 64 for(int j = 2; j <= m + 1; ++j) scanf("%d", &mat[i][j]); 65 for(int i = 1; i <= n + 2; ++i) 66 for(int j = 1; j <= m + 2; ++j) 67 if(mat[i][j] == INF) mat[i][j] = 0; 68 69 int x, y, k; 70 scanf("%d%d%d", &x, &y, &k); 71 printf("%d\n", bfs(x + 1, y + 1, k)); 72 } 73 }