北京航空航天大学 计算机机试 做题记录

此笔记是我在考研复试复习时记录

做题方法仅供参考

2023 - 1 排序输出

输入:

7

11111 A 080000 225959
22222 B 080000 225959
33333 A 100000 110000
44444 В 101000 110000
55555 A 120000 131000
66666 A 225959 235959
77777 A 100000 120000
11111

# include <iostream>
# include <vector>
# include <algorithm>

using namespace std;

const int N = 100000 + 10;

int n;

struct Log {
      string number, station, login, logout;
      bool operator < (const Log &l) const{
            if (login == l.login){
                  return number < l.number;
            }
            else return login < l.login;
      }
}logs[N];

int main (){

      cin >> n;
      string number, station, login, logout;
      for (int i = 0; i < n; i ++ ){
            cin >> number >> station >> login >> logout;
            logs[i] = {number , station , login , logout};
      }
      string q_number;
      cin >> q_number;

      vector<Log> target_logs;
      for (int i = 0; i < n; i++){
            if (logs[i].number == q_number){
                  target_logs.push_back(logs[i]);}
                  
      }
      vector<Log> res_logs;
      for (auto log : target_logs){
            for (int i = 0; i < n; i ++){
                  if (logs[i].number != q_number && logs[i].station == log.station || logs[i].number != q_number && 
                      ! (logs[i].login >= log.logout  ||  logs[i].logout <= log.login ) ){
                        res_logs.push_back(logs[i]);
                        
                      }
            }
      }
      sort(res_logs.begin(), res_logs.end());
      for (auto log : res_logs){
            cout << log.number << " " << log.station << " " << log.login << " " << log.logout << endl;
       }
}


2023-2 老鼠找吃 栈模拟

#include <iostream>
#include <cstring>
#include <vector>
#include <queue>

using namespace std;

typedef pair<int, int> PII;

const int N = 10;

string s;
int direction[5] = {0,2,1,4,3};  //下标为i的反方向

vector<PII> walk;   //行走路径
vector<PII> walk_back;  //返回路径

void find_path(){
    while (walk.size()){
        // 反方向输出路径
        auto w = walk.back();
        walk.pop_back();
        
        if (walk_back.size() > 0 && walk_back.back().first == direction[w.first]){
            walk_back.back().second += w.second;
        }
        else{
            walk_back.push_back({direction[w.first], w.second});
        }
        
    }
    
    for (auto p: walk_back){
        cout << p.first << "-" << p.second << " ";
    }
}

int main (){
    while (cin >> s){
        int a = s[0] - '0';
        int b = s[2] - '0';
        if (a == 0 && b == 0){
            find_path();
            return 0;
        }
        
        //遇到反方向,重新规划行走路径
        if(walk.size() > 0 && ( walk.back().first * a == 2 || walk.back().first * a == 12 )){
            //cout << "back" << endl;
            int a1 = walk.back().first;
            int b1 = walk.back().second;
            if (b > b1){
               walk.pop_back();
               walk.push_back({a, b-b1});
            }
            else if (b < b1){
                walk.pop_back();
                walk.push_back({a1, b1 - b});
            }
            else {
                walk.pop_back();
            }
        }
        else{
            walk.push_back({a, b});
        }
    }
    //     for (auto p: walk){
    //     cout << p.first << "-" << p.second << " ";
    // }

}

字符串匹配

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1000 + 10;

string str[N], p;
int n;

string filter(string p){
    string res;
    for (auto c : p){
        res += tolower(c);
    }
    return res;
}


bool match(string p, string str){
    for (int i = 0, j = 0; i < str.size() || j < p.size(); i++, j++){
        if (i == str.size() || j == p.size()){ //如果ij有一个到达了末尾,说明两个串长度不一样
            return false;
        }
        if (str[i] != '['){
            if (str[i] != p[j]) return false;
        }
        else{
            string s;
            i++;
            while (str[i] != ']'){  // 循环到str i = 】时
                s += str[i++];
            }
            if (s.find(p[j]) == -1) return false;  //下次执行for循环会有i+1
        }
    }
    return true;  
}

int main (){
    
    cin >> n;
    for (int i = 0; i < n; i++ ){
        cin >> str[i];
    }
    cin >> p;
    for (int i = 0; i < n; i ++){
        if (match(filter(str[i]), filter(p))){
            cout << i + 1 << " " << str[i] << endl; 
        }
    }

    
}

2021-2 机场模拟 - BFS

可以用额外的数组保存排序

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

const int N = 310;

int n;
int tr[N][3];
int cnt;
int h[N];
int w[N];

queue<int> q;

void bfs(){
    int start = 100;
    q.push(start);
    int k = 0;
    
    while(q.size()){
        int p = q.front();
        q.pop();
        for (int i = 0; i < 3; i++){
            if (tr[p][i] > 100){
                q.push(tr[p][i]);
            }
            else if (tr[p][i] > 0){
                cout << h[k++] << " " << tr[p][i] << endl;
            }
        }
    }
}


int main(){
    cin >> n;
    for (int i = 0; i < n; i++){
        int num;
        cin >> num;
        cin >> tr[num][0] >> tr[num][1] >> tr[num][2];
    }
    int num, flow;
    while (cin >> num && cin >> flow){
        w[num] = flow;
        h[cnt++] = num;
    }
    sort(h, h + cnt, [&](int a, int b){
        if (w[a] != w[b]) return w[a] > w[b];
        else return a < b;
    });
    
    bfs();
}

2021-1 空闲块

#include <iostream>
#include <vector>

using namespace std;

typedef pair<int, int> PII;

const int N = 110;

int n;
int idx;

vector<PII> blocks;

int main (){
    cin >> n;
    int start, size;
    for (int i = 0; i < n; i++ ){
        cin >> start >> size;
        blocks.push_back({start, size});
    }
    int search; // 搜索位置
    while (cin >> search){
        if (search == -1){
            for (int i = idx; i < blocks.size() + idx; i++){
                int k = i % blocks.size();
                cout << blocks[k].first << " " << blocks[k].second << endl;
             }
            return 0;
        }
        else{
            int min_size = -1;
            int find;
            for (int i = 0; i < blocks.size(); i++){
                int k = (i+idx) % blocks.size(); // k是循环中的当前下标,从idx开始,找一遍
                if (blocks[k].second >= search){
                    if(min_size==-1 || min_size > blocks[k].second ){ //如果找到更好的位置,更新最佳位置
                        min_size = blocks[k].second;
                        find = k;  // find 是最佳位置的下标
                    }
                }
            }
            if (min_size != -1){  // 如果找到最佳位置
                if (search < blocks[find].second){     // 小于空闲块大小
                    blocks[find].second -= search;
                }
                else if(search == blocks[find].second){// 等于空闲块,要删掉这个块
                    for (int j = find; j < blocks.size()-1; j++){
                        blocks[j] = blocks[j+1];
                    }
                    blocks.pop_back();
                }
                idx = find;
            }
            // 如果没找到最佳位置,相当于idx没变

        }
    }
    
}

2022-1 字符串比较

#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;

const int N = 20;

string s[N];

int n;

struct match{
    string min;
    string max;
    int res;
};

vector<match> list;

void bijiao(string a, string b){
    int res = 0;
    for (int i = 0; a[i]; i++){
        if (a[i]!= b[i]){
            res ++;
        }
        
    }
    if (a < b){
        list.push_back({a, b, res});
    }
    else{
        list.push_back({b, a, res});
    }
}

bool cmp(match a, match b){
    if (a.res == b.res){
        if (a.min == b.min){
            return a.max < b.max;
        }
        else return a.min < b.min;
    }
    else return a.res < b.res;
}

int main(){
    cin >> n;
    string a;
    for (int i = 0; i < n; i++){
        cin >> a;
        s[i] = a;
    }
    for (int i = 0; i < n; i++){
        for (int j = i + 1; j < n; j++){
            bijiao(s[i], s[j]);
        }
    }
    sort(list.begin(), list.end(), cmp); 
    if (list.size() > 6){
        for (int i = 0; i < 6; i++){
            cout << list[i].min << " " << list[i].max << " " << list[i].res << endl;  
        }
    }
    else {
        for (int i = 0; i < list.size(); i++){
            cout << list[i].min << " " << list[i].max << " " << list[i].res << endl;  
        } 
    }
}

2022-2 模拟编译-栈求中缀表达式

#include <iostream>
#include <cstring>
#include <stack>
#include <algorithm>
#include <unordered_map>

using namespace std;

const int N = 20;

char name[N];
int value[N];
unordered_map<char, int> variable;
stack<int> nums;
stack<char> ops;
unordered_map <char, int> opl = {{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};

void eval(){ //计算函数,弹出两个数字和一个操作符,计算后压栈
    auto b = nums.top(); nums.pop();
    auto a = nums.top(); nums.pop();
    auto c = ops.top(); ops.pop();
    int x;
    if (c == '+') x = a + b;
    else if (c == '-') x = a - b;
    else if (c == '*') x = a * b;
    else x = a / b;
    nums.push(x);
}

void read(){
    string s;
    getline(cin, s);  // 读入一行
    int value;
    for (int i = 0; s[i]; i++){
        if (isalpha(s[i])){
            cin >> value;
            variable[s[i]] = value;
        }
    }
}

void print(){
    string s;
    getline(cin, s);
    for (int i = 0; s[i]; i++){
        if (isalpha(s[i])){
            cout << variable[s[i]] << " ";
        }
    }
}

void calculate(string s){
    char target = s[0];
    for (int i = 2; s[i]; i++){
        if(isalpha(s[i])){
            nums.push(variable[s[i]]);
        }
        else if (isdigit(s[i])){
            int value = s[i] - '0';
            while (isdigit(s[++i])){
                value = value*10 + s[i] - '0';
            }
            i--;
            nums.push(value);
        }
        else if (s[i] == '('){
            ops.push(s[i]);
        }
        else if (s[i] == ')'){
            while (ops.top() != '(') eval();
            ops.pop();
        }
        else{
            while(ops.size() && ops.top() != '(' && opl[s[i]] <= opl[ops.top()] ) eval();
            ops.push(s[i]); //计算结束后将新操作符压入栈内
        }
    }
    while(ops.size()) eval();  //注意这里一定要判断还有没有
    variable[target] = nums.top();
    nums.pop();
}


int main(){
    string a;
    while (cin >> a){
        if( a == "exit" ){
            return 0;
        }
        else if (a == "read"){
            read();
        }
        else if (a== "print"){
            print();
        }
        else{
            calculate(a);
        }
    }
}

2019-1 素数等差数列

#include <iostream>
#include <cstring>
#include <stack>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <cmath>

using namespace std;

int a, b;

int nums[10];
int cnt;

vector<int> prime_list;

bool is_prime(int x){
    for (int i = 2; i <= sqrt(x); i++){
        if (x%i == 0) return false;
    }
    return true;
}

int main(){
    cin >> a >> b;
    for (int i = a; i <= b; i++){
        if (is_prime(i)) prime_list.push_back(i);
    }
    for (int i = 0; i < prime_list.size(); i++){
        int k = prime_list[i+1] - prime_list[i];
        nums[cnt++] = prime_list[i];
        nums[cnt++] = prime_list[i+1];
        i+=2;
        while (prime_list[i] - prime_list[i-1] == k){
            nums[cnt++] = prime_list[i];
            i++;
        }
        if (cnt >= 3){ 
            //如果长度大于3,说明前n个数字等差,从最后一个数字开始判断,不会重复
            for (int j = 0; j < cnt; j++){
                cout << nums[j] << " ";
            }
            cout << endl;
            cnt = 0;
            i-=2; //i当前是第n+1个,for循环还会加1,所以-2
        }
        else {
            // 如果长度小于3,则长度肯定为2,应该当i往前移动两位,从最后一个数字开始判断
            cnt = 0;
            i-=2;
        }
    }
    
}

2019-2 三叉树搜索节点路径-DFS

#include <iostream>
#include <cstring>
#include <stack>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <cmath>

using namespace std;

typedef pair<int, int> PII;

const int N = 10000 + 10;

int n, m;
int h[N];
int e[N];
int ne[N];
int idx;
bool st[N];
vector<int> path;
vector<PII> action;
int start;
int ending;
int root;

void add(int a, int b){
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx;
    idx ++;
}

void dfs(int u, int target){
    st[u] = true;//说明这个点已经走过去了
    if (u == target){
        for (auto t: path){
            cout << t << " ";
        }
        cout << endl;
        ending = path[path.size()-2];
        return;
    }
    for(int i = h[u]; i != -1; i = ne[i]){ //遍历u的所有子节点
        int j = e[i];   //j代表u的联通节点,u->j
        if( !st[j] ){   //这个点已经遍历过,那么看u的下一个子节点
            path.push_back(j);
            dfs(j, target); //递归j
            path.pop_back();
        }
    }
}

int main(){
    memset(h, -1, sizeof h); //邻接表别忘了这句话
    cin >> n;
    for (int i = 0; i < n; i++){
        int a[4];
        cin >> a[0] >> a[1] >> a[2] >> a[3];
        for (int  i =1; i < 4; i++){
            if (a[i] != -1){
                add(a[0], a[i]);
                add(a[i], a[0]);
            }
        }
        if (i==0) root = a[0]; 
    }
    cin >> m;
    while(m--){
        int target, pirority;
        cin >> target;
        cin >> pirority;
        action.push_back({target, pirority});
    }
    sort(action.begin(), action.end(), [&](auto a, auto b){
        return a.second < b.second;
    });
    ending = root;
    for (auto t: action){
        start = ending;
        path.push_back(start);
        dfs(start, t.first);
        path.clear();
        memset(st, false, sizeof st);
    }
    
    start = ending;
    path.push_back(start);
    dfs(start, root); //返回

}

2018-2 三叉树先序遍历找最深节点

前序遍历中,传入一个变量记录当前深度

每次遍历进行比较

#include <iostream>
#include <cstring>
#include <stack>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <queue>

using namespace std;

const int N = 10000 + 10;

int n;
int l[N], m[N], r[N];
unordered_map<int, int> child_num; // 孩子个数
int idx; 
bool st[N];
int root;
int max_depth = 0;
int max_child = 0;
int best_s;
int max_p;

void dfs(int u, int d){
    if (u == -1) return;
    idx += 1;
    if (child_num[u] >= max_child){
        if (d > max_depth){  //如果当前深度更大
            max_depth = d;
            max_child = child_num[u];
            max_p = u;
            best_s = idx;
        }
    }
    dfs(l[u], d+1);
    dfs(m[u], d+1);
    dfs(r[u], d+1);
}


int main(){
    cin >> n;
    // 设置叶子节点没有孩子
    memset(l, -1, sizeof l);
    memset(m, -1, sizeof m);
    memset(r, -1, sizeof r);
    for(int i = 0; i < n; i++){
        int cnt = 0;  // 空节点个数
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        if (i == 0) root = a; //第一次记录root
        if (d == -1) cnt ++;
        if (b == -1) cnt ++;
        if (c == -1) cnt ++;
        l[a] = b;
        m[a] = c;
        r[a] = d;
        child_num[a] = 3 - cnt;
        
    }
    dfs(root, 1);
    cout << max_p << " " << best_s;
    

}

2017-3 共同父亲

lca算法

#include <iostream>
#include <cstring>
#include <stack>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <queue>

using namespace std;

const int N = 10000 + 10;

unordered_map<string,string> l, r, p;
unordered_map<string,int> d;
string root;

void dfs(string p, int dis){
    if (p == "-1") return;
    d[p] = dis;
    dfs(l[p], dis+1);
    dfs(r[p], dis+1);
}

string find_lca(string a, string b){
    if (d[a] < d[b]) return find_lca(b, a);
    while (d[a] > d[b]) a = p[a];
    while (a != b) a = p[a], b = p[b];
    return a;
}


int main(){
    string str;
    string f, s1, s2;
    string a, b;
    int i = 0;
    while (getline(cin, str)){
        int pos = str.find(' ');
        f = str.substr(0, pos);
        if (i == 0) root = f;
        string child = str.substr(pos+1);
        if (child.find(' ') != -1 ){
            int pos = child.find(' ');
            s1 = child.substr(0,pos);
            s2 = child.substr(pos+1);
            l[f] = s1;
            r[f] = s2;
            p[s1] = f;
            p[s2] = f;
            l[s1] = "-1";
            r[s2] = "-1";
            r[s1] = "-1";
            l[s2] = "-1";
        }
        else{
            a = f;
            b = child;
        }
        i++;
    }
    dfs(root, 1);
    cout << find_lca(a, b) << " " << abs(d[a] - d[b]);

}

2016-1 逆序数

#include <iostream>
#include <cstring>
#include <stack>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <queue>

using namespace std;

const int N = 10000 + 10;

int main(){
    string s = "";
    int a = 0;
    int b = 0;
    char c;
    while(cin >> c){
        s += c;
        a = a * 10 + c - '0';
    }   
    int l = s.size();
    for (int i = 0; i < l/2; i++){
        char a = s[i];
        s[i] = s[l-1-i];
        s[l-1-i] = a;
    }
    for (int i = 0; s[i]; i++){
        b = b*10 + s[i] - '0';
    }
    if(b%a == 0){
        int k = b/a;
        cout << a << '*' << k << '=' << b;
    }
    else cout << a << " " << s;

}

2015-2 窗口

#include <bits/stdc++.h>
using namespace std;
const int N=15;

int n,m;

struct Window {
      int x1,y1,x2,y2;
      int id;

}window[N];

int getid(int x, int y)
{
      for (int i = n-1; i>=0; i--){
            int x1 = window[i].x1;
            int y1 = window[i].y1;
            int x2 = window[i].x2;
            int y2 = window[i].y2;
            if(x >= x1 && x<= x2 && y>=y1 &&y<=y2){
                  cout << window[i].id << endl;
                  return  i;
            }
      }
      return -1;
}

int main()
{
      cin>> n>>m;
      for (int i=0; i<n; i++){
            int x1, x2, y1, y2;
            cin >> x1>> y1 >> x2>> y2;
            window[i] = {x1, y1,x2, y2, i+1};
      }
      for (int i=0; i<m; i++){
            int x, y;
            cin >> x >> y;
            int out = getid(x,y);
            if (out==-1){
                  cout<< "IGNORED" << endl;
            }
            else{
                  auto w = window[out];
                  for (int t = out; t<n; t++){
                        window[t] = window[t+1];
                  }
                  window[n-1]= w;
            }
      }
}
  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柳_成林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值