网易游戏不统一笔试分享
投的很晚,9月26才收到笔试,笔试只有两道编程题。两题题目都很长有点唬人,其实就是按照规则模拟就好了,没有涉及具体算法。
第一题:重力模拟
有 n * m 个格子,每个格子要么是物体,要么是空白,物体有编号,每个编号对应可能会收到重力影响下坠到第 n 行,也可能不受重力影响(由一个数组 b 给出)。求出格子最后的状态。
挺简单的10分钟秒了。
#include <bits/stdc++.h>
using namespace std;
int main () {
int T;
cin >> T;
while (T--) {
int n, m, k; cin >> n >> m >> k;
vector<vector<int>> a(n + 2, vector<int>(m + 2));
for (int i = 1;i <= n;i ++)
for (int j = 1;j <= m;j++) cin >> a[i][j];
vector<int>b(k + 2);
for (int i = 1;i <= k;i++) cin >> b[i];
for (int j = 1;j <= m;j++) {
// last 记录会掉落到哪里就好了
int last = n;
for (int i = n;i;i--) {
if (a[i][j] == 0) continue;
// 受重力影响,掉到 last
if (b[a[i][j]]) {
a[last][j] = a[i][j];
if (last != i) a[i][j] = 0;
last --;
} else last = i - 1;
}
}
for (int i = 1;i <= n;i ++) {
cout << a[i][1];
for (int j = 2;j <= m;j++) {
cout << " " << a[i][j];
}
cout << endl;
}
}
return 0;
}
第二题:蛋仔派对模拟
敌我两方有若干个蛋仔,可以互相攻击和移动。有攻击范围,血量,攻击力
每个回合,每个蛋仔会同时攻击对方最近的蛋仔,即使血量调到0以下也会攻击和受到攻击。
如果攻击不到,就会移动一格。先结算攻击,死了的蛋仔移出游戏,再移动(只有我方会移动,敌方不会)
有个坑点是蛋仔攻击了就不能移动了,没考虑这个会过 90%
判断最后是我方赢还是敌方赢(同归于尽算对方赢)
我是用链表保存敌我两方蛋仔情况,然后模拟就好了,慢慢悠悠写了40分钟。
#include <bits/stdc++.h>
using namespace std;
/*
第一行输入四个正整数 N,M,p,q (1 ≤ N ≤ 100; 1 ≤ M ≤ 100; 1 ≤ p ≤ 100; 1 ≤ q ≤ 100),表示战斗盘的高和宽,我方蛋仔数量和敌方蛋仔数量。
接下来 p 行,每行输入五个正整数,HP、ATK、DIST、originX 和 originY,前三个取值范围均为 [1, 100],最后两个取值范围分别为 [0, M − 1] 和 [0, N − 1]。表示我方蛋仔的属性和位置。
接下来 q 行,每行输入的数据格式和前面 p 行一致。表示敌方蛋仔的属性和位置。
蛋仔在输入中的顺序代表蛋仔在队伍中的排名。
*/
struct egg {
int hp, atk, dist, x, y;
};
struct node {
node * next;
node * pre;
egg e;
node() : next(nullptr), pre(nullptr) {};
node(egg e) : e(e), next(nullptr), pre(nullptr) {};
};
inline int get_dist(const node *x, const node *y) {
return abs(x->e.x - y->e.x) + abs(x->e.y - y->e.y);
}
void print_egg(const egg e) {
cout << e.atk << " " << e.hp << " " << e.dist << " " << e.x << " " << e.y << endl;
}
unordered_map<node *, bool> vis;
void attack_on_list(node *my, node *enemy) {
node *cur = my->next;
while (cur) {
node *ecur = enemy->next;
node *target;
int mi = INT_MAX;
// 找到最近/排名最靠前的敌人
while (ecur) {
int now_dist = get_dist(cur, ecur);
if (now_dist < mi) {
target = ecur;
mi = now_dist;
}
ecur = ecur->next;
}
// 仅攻击
if (mi <= cur->e.dist) {
target->e.hp -= cur->e.atk;
vis[cur] = true;
}
cur = cur->next;
}
}
void check_alive(node *my) {
node *cur = my->next;
while (cur) {
node *next = cur->next;
if (cur->e.hp <= 0) {
cur->pre->next = next;
if (next) next->pre = cur->pre;
delete cur;
}
cur = next;
}
}
void move_on_list(node *my, node *enemy) {
node *cur = my->next;
while (cur) {
node *ecur = enemy->next;
node *target = nullptr;
int mi = INT_MAX;
// 找到最近/排名最靠前的敌人
while (ecur) {
int now_dist = get_dist(cur, ecur);
if (now_dist < mi) {
target = ecur;
mi = now_dist;
}
ecur = ecur->next;
}
if (target == nullptr || mi <= cur->e.dist || vis.count(cur)) {cur = cur->next;continue;}
// 移动:优先沿 y 轴移动。 如果我方蛋仔与敌方蛋仔处于同y轴坐标时,则沿 x 轴方向移动。
if (target->e.y > cur->e.y) cur->e.y ++;
else if(target->e.y < cur->e.y) cur->e.y--;
else if(target->e.x > cur->e.x) cur->e.x++;
else cur->e.x--;
cur = cur->next;
}
}
int main () {
int T;
cin >> T;
while (T--) {
int n, m, p, q; cin >> n >> m >> p >> q;
node *my = new node(), *cur = my;
node *enemy = new node(), *ecur = enemy;
int hp, atk, dist, x, y;
for (int i = 1;i <= p;i ++) {
cin >> hp >> atk >> dist >> x >> y;
cur->next = new node({hp, atk, dist, x, y});
cur->next->pre = cur;
cur = cur->next;
}
for (int i = 1;i <= q;i ++) {
cin >> hp >> atk >> dist >> x >> y;
ecur->next = new node({hp, atk, dist, x, y});
ecur->next->pre = ecur;
ecur = ecur->next;
}
while (my->next && enemy->next) {
vis.clear();
// 我方进攻
attack_on_list(my, enemy);
// 敌方进攻
attack_on_list(enemy, my);
// 检测存活
check_alive(my);
check_alive(enemy);
// 我方移动
move_on_list(my, enemy);
}
if (my->next == nullptr) cout << "NO" << endl;
else cout << "YES" << endl;
delete my;
delete enemy;
}
return 0;
}
蚂蚁集团公司福利 311人发布
查看16道真题和解析