西山居2024年秋招游戏开发A卷编程题
1.斐波那契
2.由0(海洋), 1(陆地), 2(有敌军的陆地)组成的二维网格, 计算没有敌军驻兵的岛屿数量。岛屿由水平或竖直方向相邻的陆地链接而成
#include <bits/stdc++.h> using namespace std; struct position { int i; int j; position(int i, int j) { this->i = i; this->j = j; } }; bool PositionInIslands(int i, int j, vector<vector<position>> islands) { if(islands.size() == 0) return false; for(auto island : islands) { for(auto pos : island) { if(pos.i == i && pos.j == j) return true; } } return false; } void Find(int i, int j, vector<vector<int>>& data, vector<position>& island) { data[i][j] = 0; island.emplace_back(position(i, j)); int n = data.size(); int m = data[0].size(); if(i - 1 >= 0 && data[i - 1][j] != 0) Find(i-1, j, data, island); if(i + 1 < n && data[i + 1][j] != 0) Find(i+1, j, data, island); if(j - 1 >= 0 && data[i][j - 1] != 0) Find(i, j - 1, data, island); if(j + 1 < m && data[i][j + 1] != 0) Find(i, j + 1, data, island); } int CountEmptyIsland(vector<vector<int>>& data) { // 复制用于最后判定 vector<vector<int>> copy_data(data); // 组成岛屿的位置 vector<vector<position>> islands; for(int i = 0; i < data.size(); ++i) { for(int j = 0; j < data[0].size(); ++j) { // 是陆地 if(data[i][j] == 1 || data[i][j] == 2) { // 陆地不包含在其他岛屿 if(!PositionInIslands(i, j, islands)) { vector<position> island; // 找相邻陆地构成的岛屿 Find(i, j, data, island); islands.emplace_back(island); } } } } int ans = islands.size(); for(auto island : islands) { for(auto pos : island) { if(copy_data[pos.i][pos.j] == 2) { ans--; break; } } } return ans; } int main(void) { int n, m; cin >> n; cin >> m; vector<vector<int>> data(n, vector<int>(m)); for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { cin >> data[i][j]; } } cout << CountEmptyIsland(data) << endl; return 0; }
3.实现简单的网络协议解码器, 从标准输入得到模拟的网络字节流, 对其解码并输出解析后的内容
|检验码 2bytes|长度 2bytes|协议号 2bytes|消息体 n bytes|
字节流前两个字节为常量, 设置为"SS"
接下来两个字节为协议的长度 unsigned short
接着是两个字节的协议号 unsigned short
最后是消息
每个字节流输入可能有多条协议, 并且最后一条协议不一定完整, 需要进行解码并输出.
如果有多条协议, 解析出字节流内完整的协议, 然后每条协议输出一行.
#include <bits/stdc++.h> using namespace std; uint16_t CharToUint(char c) { uint16_t i = 0; if (isdigit(c)) { i += c - '0'; } else { i += c - 'a' + 10; } return i; } uint16_t StrToUint(string str) { uint16_t i = 0; // index 1,0,3,2 i += CharToUint(str[1]); i += CharToUint(str[0]) * 16; i += CharToUint(str[3]) * 16 * 16; i += CharToUint(str[2]) * 16 * 16 * 16; return i; } void Split(string message, vector<string>& messages) { uint16_t len; while (message.substr(0, 4) == "5353") { // 解码长度 len = StrToUint(message.substr(4, 4)); // 是否完整 if (message.size() - 8 >= len) { messages.push_back(message.substr(8, len * 2)); message = message.substr(8 + len * 2, message.size() - 8 - len * 2); } else { break; } } } void Decode(string m) { uint16_t num; string body = ""; num = StrToUint(m.substr(0, 4)); // 减去协议号 m = m.substr(4, m.size() - 4); // 每两个字符进行解码 for (int i = 0; i < m.size(); i += 2) { char c = 0; c += CharToUint(m[i + 1]); c += CharToUint(m[i]) * 16; body += c; } cout << num << " " << body << endl; } int main(void) { // 示例1 // string message = "53530e00420048656c6c6f2053656153756e"; // 示例2 // string message = // "53530e00420048656c6c6f2053656153756e53531300580057656c636f6d6520746f205a6875486169"; // 示例3 string message = "53530e00420048656c6c6f2053656153756e53531300580057656c636f6d6520746f20" "5a687548616953530b007b00476f6f64206c75636b53530f00"; vector<string> messages; Split(message, messages); for (string str : messages) { Decode(str); } return 0; }