hihocoder 网易游戏2016实习生招聘在线笔试 解题报告

时间:2023-03-10 04:06:59
hihocoder 网易游戏2016实习生招聘在线笔试 解题报告

比赛笔试链接:http://hihocoder.com/contest/ntest2015april/problems

题目就不贴了。

1、推箱子。

思路:纯模拟。

代码(28MS):

 #include <bits/stdc++.h>
using namespace std; const int MAXV = ; const char str_op[] = "dulr";
int fx[] = {, -, , };
int fy[] = {, , -, }; inline int id(char c) {
static const char op[] = "dulr";
return strchr(op, c) - op;
} char op[MAXV];
int len;
char mat[][];
int n, m, s; int sx, sy, vx, vy, ex, ey; void init() {
for(int i = ; i <= n; ++i)
for(int j = ; j <= m; ++j) {
if(mat[i][j] == '') sx = i, sy = j;
if(mat[i][j] == '') ex = i, ey = j;
if(mat[i][j] == '') vx = i, vy = j;
}
} bool solve() {
int x1 = sx, y1 = sy, x2 = vx, y2 = vy;
for(int i = ; i < len; ++i) {
int f = id(op[i]);
int new_x = x1 + fx[f], new_y = y1 + fy[f];
if(new_x == x2 && new_y == y2) {
int pp = x2 + fx[f], qq = y2 + fy[f];
if(mat[pp][qq] != '') {
x1 = new_x, y1 = new_y;
x2 = pp, y2 = qq;
}
} else if(mat[new_x][new_y] != '') {
x1 = new_x, y1 = new_y;
}
if(x2 == ex && y2 == ey) return true;
}
return false;
} int main() {
memset(mat, '', sizeof(mat));
scanf("%d%d%d", &m, &n, &s);
for(int i = ; i <= n; ++i)
for(int j = ; j <= m; ++j) scanf(" %c", &mat[i][j]);
init();
while(s--) {
scanf("%d %s", &len, op);
puts(solve() ? "YES" : "NO");
}
}

2、井字棋

思路:俗称井字过三关。题目没有提到的三种不合法情况:

①XO都有3连

②X有3连,但是count(X)=count(O)

③O有3连,但是count(X)-1=count(O)

其他不难。人工手动枚举大法好。简单粗暴不易出错。

不过我又成功在通过样例之前把代码交了上去导致WA20(不算罚时就是好啊)

代码(15MS):

 #include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long LL; int f[][] = {
{, , },
{, , },
{, , },
{, , },
{, , },
{, , },
{, , },
{, , }
}; char mat[];
int wino[], winx[];
int T; void build_check(int win[], char c) {
for(int i = ; i < ; ++i) {
win[i] = ;
for(int j = ; j < ; ++j)
if(mat[f[i][j]] != c) win[i] = ;
}
} int build_count(char c) {
return count(mat, mat + , c);
} bool next_win(char c) {
int win[];
for(int i = ; i < ; ++i) if(mat[i] == '_') {
mat[i] = c;
build_check(win, c);
if(count(win, win + , )) return true;
mat[i] = '_';
}
return false;
} int solve() {
int xcnt = build_count('X'), ocnt = build_count('O');
if(xcnt != ocnt && xcnt - != ocnt) return puts("Invalid"); build_check(winx, 'X');
build_check(wino, 'O');
if(count(winx, winx + , ) > && count(wino, wino + , ) > ) return puts("Invalid");
if(count(winx, winx + , ) > && xcnt == ocnt) return puts("Invalid");
if(count(wino, wino + , ) > && xcnt - == ocnt) return puts("Invalid"); if(count(winx, winx + , ) > ) return puts("X win");
if(count(wino, wino + , ) > ) return puts("O win"); if(build_count('_') == ) return puts("Draw"); if(next_win(xcnt == ocnt ? 'X' : 'O')) return puts("Next win");
return puts("Next cannot win");
} int main() {
scanf("%d", &T);
while(T--) {
scanf("%s", mat);
scanf("%s", mat + );
scanf("%s", mat + );
solve();
}
}

3、连连看

思路:参照最小转弯问题:http://www.cnblogs.com/oyking/p/3756208.html

估计直接来个heap+dijkstra也能100分把。

代码(302MS):

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std; const int MAXN = ;
const int INF = 0x3f3f3f3f; struct Node {
int f, x, y;
Node() {}
Node(int f, int x, int y):
f(f), x(x), y(y) {}
}; int fx[] = {-, , , };
int fy[] = {, , , -}; int dis[][MAXN][MAXN];
int mat[MAXN][MAXN];
bool vis[MAXN][MAXN];
int T, n, m; int bfs(int x1, int y1, int k) {
memset(vis, , sizeof(vis)); vis[x1][y1] = true;
memset(dis, 0x3f, sizeof(dis));
queue<Node> *now = new queue<Node>();
queue<Node> *nxt = new queue<Node>();
int step = , res = ;
for(int i = ; i < ; ++i) now->push(Node(i, x1, y1));
for(int i = ; i < ; ++i) dis[i][x1][y1] = ;
while(step <= k && !now->empty()) {
Node t = now->front(); now->pop();
if(dis[t.f][t.x][t.y] != step) continue;
for(int i = ; i < ; ++i) {
if((t.f + ) % == i) continue;
int x = t.x + fx[i], y = t.y + fy[i], d = dis[t.f][t.x][t.y] + (t.f != i);
if(mat[x][y] == mat[x1][y1] && !vis[x][y] && d <= k) {
vis[x][y] = true;
res++;
}
if(mat[x][y] == && d < dis[i][x][y]) {
dis[i][x][y] = d;
if(t.f == i) now->push(Node(i, x, y));
else nxt->push(Node(i, x, y));
}
}
if(now->empty()) {
step++;
swap(now, nxt);
}
}
return res;
} int main() {
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
memset(mat, 0x3f, sizeof(mat));
for(int i = ; i <= n + ; ++i)
for(int j = ; j <= m + ; ++j) scanf("%d", &mat[i][j]);
for(int i = ; i <= n + ; ++i)
for(int j = ; j <= m + ; ++j)
if(mat[i][j] == INF) mat[i][j] = ; int x, y, k;
scanf("%d%d%d", &x, &y, &k);
printf("%d\n", bfs(x + , y + , k));
}
}