提交记录 14239


用户 题目 状态 得分 用时 内存 语言 代码长度
soulhammer router32. 测测你的路由器 Accepted 100 377.737 ms 122624 KB C++ 3.54 KB
提交时间 评测时间
2020-09-18 21:39:05 2020-09-18 21:39:12
#include "router.h"
#include <stdint.h>
#include <stdlib.h>
#include <arpa/inet.h>

/*
  RoutingTable Entry 的定义如下:
  typedef struct {
    uint32_t addr; // 大端序,IPv4 地址
    uint32_t len; // 小端序,前缀长度
    uint32_t if_index; // 小端序,出端口编号
    uint32_t nexthop; // 大端序,下一跳的 IPv4 地址
  } RoutingTableEntry;

  约定 addr 和 nexthop 以 **大端序** 存储。
  这意味着 1.2.3.4 对应 0x04030201 而不是 0x01020304。
  保证 addr 仅最低 len 位可能出现非零。
  当 nexthop 为零时这是一条直连路由。
  你可以在全局变量中把路由表以一定的数据结构格式保存下来。
*/

void copyEntry(RoutingTableEntry * entry, RoutingTableEntry oldEntry) {
  entry -> addr = oldEntry.addr;
  entry -> len = oldEntry.len;
  entry -> nexthop = oldEntry.nexthop;
}

struct Node {
  bool left = true;
  int entryNum = 0;
  RoutingTableEntry * entry = nullptr;
  Node * parent = nullptr;
  Node * lNode = nullptr, * rNode = nullptr;
};

class RoutingTrie {
  static Node * root;
public:
  static RoutingTableEntry * search(uint32_t addr) {
    uint32_t newAddr = ntohl(addr);
    Node * node = root;
    RoutingTableEntry * entry = root -> entry;
    for (int i = 0; i < 32; i ++) {
      int bit = newAddr >> 31;
      node = (bit == 0) ? node -> lNode : node -> rNode;
      if (node != nullptr) {
        entry = (node -> entry == nullptr) ? entry : node -> entry; 
      } else {
        break;
      }
      newAddr = newAddr << 1;
    }
    return entry;
  }

  static void insertNode(RoutingTableEntry entry) {
    uint32_t addr = ntohl(entry.addr);
    int len = entry.len;
    Node * node = root;

    for (int i = 0; i < len; i ++) {
      int bit = addr >> 31;
      if (bit == 0) {
        if (node -> lNode == nullptr) {
          node -> lNode = new Node;
          node -> lNode -> parent = node;
        }
        node = node -> lNode;
      } else {
        if (node -> rNode == nullptr) {
          node -> rNode = new Node;
          node -> rNode -> parent = node;
          node -> rNode -> left = false;
        }
        node = node -> rNode;
      }
      addr = addr << 1;
    }

    if (node -> entry != nullptr) {
      if (node -> entry -> addr == entry.addr) {
        copyEntry(node -> entry, entry);
      } else {
        node -> entryNum ++;
      }
    } else {
      node -> entry = new RoutingTableEntry;
      copyEntry(node -> entry, entry);
      node -> entryNum ++;
    }
  }
  
  static void deleteNode(RoutingTableEntry entry) {
    uint32_t addr = ntohl(entry.addr), len = entry.len;
    Node * node = root;
    while (len != 0) {
      int bit = addr >> 31;
      node = (bit == 0) ? node -> lNode : node -> rNode;
      if (node != nullptr) {
        addr = addr << 1;
        len --;
      } else {
        break;
      }
    }
    if (len == 0) { //find node
      while (node != root) {
        if (node -> entryNum > 0)
          node -> entryNum --;
        if (node -> entryNum == 0) {
          if (node -> lNode == nullptr && node -> rNode == nullptr) {
            bool leftNode = node -> left;
            node = node -> parent;
            if (leftNode) {
              delete node -> lNode;
              node -> lNode = nullptr;
            } else {
              delete node -> rNode;
              node -> rNode = nullptr;
            }
          } else {
            node -> entry = nullptr;
            break;
          }
        }
      }
    }
  }

};

Node * RoutingTrie::root = new Node;

void init(int n, int q, const RoutingTableEntry *a) {
  for (int i = 0; i < n; i ++) {
    RoutingTrie::insertNode(a[i]);
  }
}

unsigned query(unsigned addr) {
  RoutingTableEntry * entry = RoutingTrie::search(addr);
  if (entry != nullptr) {
    return entry -> nexthop;
  }
  return 0;
}

CompilationN/AN/ACompile OKScore: N/A

Testcase #112.34 us28 KBAcceptedScore: 25

Testcase #265.076 ms119 MB + 768 KBAcceptedScore: 25

Testcase #3221.855 ms119 MB + 768 KBAcceptedScore: 25

Testcase #4377.737 ms119 MB + 768 KBAcceptedScore: 25


Judge Duck Online | 评测鸭在线
Server Time: 2024-12-05 10:25:47 | Loaded in 0 ms | Server Status
个人娱乐项目,仅供学习交流使用 | 捐赠