网易游戏不统一笔试分享
投的很晚,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; }