2021华为软件精英挑战赛总结

一、前言

去年大二,在近似满课和C++连vector都不知道是啥的基础上,经过一个月和队友的现学,我负责数据结构和算法、队友负责IO和多线程,最终获得杭厦初赛正赛26(单线程)复赛正赛第9(多线程)的成绩。
在这里插入图片描述

今年壮志凌云,想着冲击一下全国总决赛,结果理想很丰满现实很骨感。这次题目更拼思路和灵感,队内配合不好,近似单挑地完成了比赛,最后没有进入复赛,止步64弱,很遗憾。
3月13号考完pat那天写的baseline没想到竟成了本次比赛的最高排名,之后便一直掉…
在这里插入图片描述

练习赛最后第21名
在这里插入图片描述
正式赛第48名
在这里插入图片描述
练习赛最好那份代码在正式赛超时了,最后是通过玄学调参在迁移部分控制服务器遍历的次数上限来减少了时间,不过算了下练习赛和正式赛我的代码迁移部分节省的成本都是4000w左右,所以应该也到优化的极限了,AB榜排名相差这么大没进入复赛可能确实是赛区藏分的家伙太多了,我估计A榜进1090的就有30个左右。因为正式赛代码涉及玄学调参,调参是面向数据集的没什么意思,所以就不放上来了,大方向和思路就是练习阶段这样。

二、思路

按天处理,按天输出;处理分三步:填、买、迁。填和买同步进行,按照“删除请求”为分界线来分阶段对一天中的所有虚拟机请求排序,排序规则是(CPU+内存)需求大的虚拟机请求优先处理,无法分配到已购买服务器上的虚拟机就购买新的服务器。

预处理

读入数据后,将服务器和虚拟机信息存到结构体中,因为所有服务器都是双节点,故服务器的CPU和内存大小可以直接除以2存储,因为购买服务器时是遍历服务器列表找到第一个满足条件的购买,所以服务器列表的顺序很重要。先根据服务器的购买成本对所有服务器进行排序:

bool cmp1_2(const Server &a, const Server &b){
  return a.Hardware_cost != b.Hardware_cost ? a.Hardware_cost < b.Hardware_cost : a.Energy_cost < b.Energy_cost;
}

填充策略

对每一个虚拟机请求,都遍历一遍已购买服务器列表,对于每台服务器有四个资源量分别是A节点CPU、A节点内存、B节点CPU、B节点内存,在保证虚拟机能分到该服务器的前提下,选择剩余资源最少的那个服务器填进去,判断剩余资源最少的方案如下所示:

int aC = mySer[j].aidleCPU - nCPU;
int aR = mySer[j].aidleRAM - nRAM;
int bC = mySer[j].bidleCPU - nCPU;
int bR = mySer[j].bidleRAM - nRAM;
int temp1 = max(aC, bC);
int temp2 = max(aR, bR);
int temp = max(temp1, temp2);
if(temp < minCR){
	minCR = temp;
	p = j;
}

购买策略

预处理时已经按照价格对所有服务器排了序,买第一个资源方面符合条件且最便宜的那个就完事儿了!

int magic_search(int target_CPU, int target_RAM){
  for(int i=1; i<=N; i++){
    if(ser[i].CPU >= target_CPU && ser[i].RAM >= target_RAM){
      return i;
    }
  }
  return -1;
}

迁移策略

在每天的最后处理,策略就是优先迁移挂载虚拟机数量少的服务器,如果虚拟机数量相同,则优先迁移每日能耗贵的服务器。如果一台服务器上的虚拟机能全部迁出才迁,否则不迁排序函数如下:

bool cmp2_2(int a, int b){
  return mySer[a].VMnum != mySer[b].VMnum ? mySer[a].VMnum < mySer[b].VMnum :  mySer[a].Energy_cost > mySer[b].Energy_cost;
}

三、代码

A榜1102891453无调参

#include <bits/stdc++.h>
#include <chrono> 
using namespace std;
using namespace chrono;

#define INF 0x3f3f3f3f

//#define LOCAL_TEST
#define MIGRATE

const char cm = ',';
const char ch = '.';
const char lb = '(';
const char rb = ')';
const char nl = '\n';

const int maxn = 105;
const int maxm = 1005;
const int maxt = 1005;
const int maxr = 100005;

template <typename T>
struct Vector {
  T *a;
  int n;
  Vector() {
    a = nullptr;
    n = 0;
  }
  void push_back(T x) {
    if ((n & -n) == n) {
      a = (T*)realloc(a, (n * 2 + 1) * sizeof(T));
    }
    a[n++] = x;
  }
  struct Iterator {
    int index;
    Vector& outer;
    Iterator(Vector &o, int i): outer(o), index(i) { }
    void operator++() {
      ++index;
    }
    T& operator*() const {
      return outer.a[index];
    }
    bool operator !=(const Iterator& i) {
      return i.index != index;
    }
  };
  Iterator begin() {
    return Iterator(*this, 0);
  }
  Iterator end() {
    return Iterator(*this, n);
  }
};

int N, M, T, R, Q, W, id = 0, myid = 0;
int idhash[maxr]; //myid->id

int requestCPU = 0, requestRAM = 0;

#ifdef LOCAL_TEST
const char *testFile = "training-1.txt";
const char *resultFile = "result-1.txt";
bool if_w = true;
int money = 0, money1 = 0;
#endif

unordered_map<string, int>SerHash,VMHash;

/*服务器类型信息  二分资源*/
struct Server{
  string TYPE;
  int CPU, RAM, Hardware_cost, Energy_cost;
}ser[maxn];

bool cmp1_1(const Server &a, const Server &b){
  return a.Energy_cost != b.Energy_cost ? a.Energy_cost < b.Energy_cost : a.Hardware_cost < b.Hardware_cost;
}

bool cmp1_2(const Server &a, const Server &b){
  return a.Hardware_cost != b.Hardware_cost ? a.Hardware_cost < b.Hardware_cost : a.Energy_cost < b.Energy_cost;
}

/*虚拟机类型信息*/
struct VM{
  string TYPE;
  int CPU, RAM, is_Even;
}vm[maxm];

struct GoMOVE{
  int ADDid, SUM_CR, CPU, RAM;
  friend bool operator <(const GoMOVE &a, const GoMOVE &b){
    if(a.SUM_CR != b.SUM_CR){
      return a.SUM_CR < b.SUM_CR;
    }else{
      if(requestRAM < requestCPU){
        return a.RAM < b.RAM;
      }else{
        return a.CPU < b.CPU;
      }
    }
  }
};

unordered_map<int, int>addidhash;
int addtovmid[maxr];

struct ADD{
  int CPU, RAM, is_Even, Serid, Sernode, End_Time, CRSUM;
}add[maxr];
int addindex = 1;
int nowadd = 0;

bool cmp3_1(int a, int b){
  if(add[a].CRSUM != add[b].CRSUM){
    return add[a].CRSUM > add[b].CRSUM;
  }else{
    if(requestRAM > requestCPU){
      return add[a].RAM > add[b].RAM;
    }else{
      return add[a].CPU > add[b].CPU;
    }
  }
}

int del[maxr]; //记录删除的add序号
int delindex = 1;
int nowdel = 0;

/*获取当前可调度虚拟机上限*/
int getmove(int n){
  return (int)((1.0 * 5 * n) / 1000);
}

Vector<int> task[maxt];

void read(){
#ifdef LOCAL_TEST
  freopen(testFile,"rb",stdin);
#endif
  scanf("%d",&N);
  string OP,TYPE,CPU_cores,RAM_size,Hardware_cost,Energy_cost,is_Even,VM_id;
  for(int cnt=1; cnt<=N; ++cnt){
    cin>>TYPE>>CPU_cores>>RAM_size>>Hardware_cost>>Energy_cost;
    TYPE.erase(TYPE.begin());
    TYPE.erase(TYPE.end()-1);
    ser[cnt].TYPE = TYPE;
    CPU_cores.erase(CPU_cores.end()-1);
    ser[cnt].CPU = stoi(CPU_cores)/2;
    RAM_size.erase(RAM_size.end()-1);
    ser[cnt].RAM = stoi(RAM_size)/2;
    Hardware_cost.erase(Hardware_cost.end()-1);
    ser[cnt].Hardware_cost = stoi(Hardware_cost);
    Energy_cost.erase(Energy_cost.end()-1);
    ser[cnt].Energy_cost = stoi(Energy_cost);
  }
  scanf("%d",&M);
  for(int cnt=1; cnt<=M; ++cnt){
    cin>>TYPE>>CPU_cores>>RAM_size>>is_Even;
    TYPE.erase(TYPE.begin());
    TYPE.erase(TYPE.end()-1);
    vm[cnt].TYPE = TYPE;
    VMHash[TYPE] = cnt;
    CPU_cores.erase(CPU_cores.end()-1);
    vm[cnt].CPU = stoi(CPU_cores);
    RAM_size.erase(RAM_size.end()-1);
    vm[cnt].RAM = stoi(RAM_size);
    if(is_Even[0] == '1'){
      vm[cnt].is_Even = 1;
    }else{
      vm[cnt].is_Even = 0;
    }
  }
  sort(ser+1,ser+N+1,cmp1_2);
  for(int cnt=1; cnt<=N; ++cnt){
    SerHash[ser[cnt].TYPE]=cnt;
  }
  scanf("%d",&T);
  for(int cnt=1; cnt<=T; ++cnt){
    scanf("%d",&R);
    for(int i=0; i<R; ++i){
      cin>>OP;
      if(OP[1]=='a'){
        cin>>TYPE>>VM_id;
        TYPE.erase(TYPE.end()-1);
        VM_id.erase(VM_id.end()-1);
        addidhash[stoi(VM_id)] = addindex;
        addtovmid[addindex] = stoi(VM_id);
        VM now = vm[VMHash[TYPE]];
        add[addindex].CPU = now.CPU;
        add[addindex].RAM = now.RAM;
        requestCPU += now.CPU;
        requestRAM += now.RAM;
        add[addindex].CRSUM = now.CPU + now.RAM;
        add[addindex].is_Even = now.is_Even;
        add[addindex].Serid = -1;
        add[addindex].Sernode = -1;
        add[addindex].End_Time = T+1;
        task[cnt].push_back(addindex);
        ++addindex;
      }else{
        cin>>VM_id;
        VM_id.erase(VM_id.end()-1);
        int addid = addidhash[stoi(VM_id)];
        del[delindex] = addid;
        add[addid].End_Time = cnt;
        task[cnt].push_back((0-delindex));
        ++delindex;
      }
    }
  }
#ifdef LOCAL_TEST
  fclose(stdin);
#endif
  return ;
}

struct CEO{
  int Serid,node; //对虚拟机请求的分配方案
};

void output(vector<CEO> &a){
#ifdef LOCAL_TEST
  freopen(resultFile,"a",stdout);
#endif
  for(auto &x:a){
    printf("(%d",idhash[x.Serid]);
    if(x.node==1){
      printf(", A");
    }else if(x.node==2){
      printf(", B");
    }
    printf(")\n");
  }
#ifdef LOCAL_TEST
  fclose(stdout);
#endif
  return ;
}

struct Purchase{
  string TYPE;  //服务器类型
  int num;  //数量
};

void outputq(vector<Purchase>&a, int sum){
#ifdef LOCAL_TEST
  if(if_w){
    freopen(resultFile,"w",stdout);
    if_w = false;
  }else{
    freopen(resultFile,"a",stdout);
  }
#endif
  printf("(purchase, %d)\n",sum);
  for(auto &x:a){
    printf("(%s, %d)\n",x.TYPE.c_str(),x.num);
  }
#ifdef LOCAL_TEST
  fclose(stdout);
#endif
  return ;
}

struct Migration{
  int VMid,Serid,node; //虚拟机id、服务器id、node=1(A), node=2(B), node=0(?)
};

void outputw(vector<Migration>&a, int sum){
#ifdef LOCAL_TEST
  freopen(resultFile,"a",stdout);
#endif
  printf("(migration, %d)\n",sum);
  for(auto &x:a){
    printf("(%d, %d",x.VMid,idhash[x.Serid]);
    if(x.node==1){
      printf(", A");
    }else if(x.node==2){
      printf(", B");
    }
    printf(")\n");
  }
#ifdef LOCAL_TEST
  fclose(stdout);
#endif
  return ;
}

struct MyServer{
  string TYPE;
  int aidleCPU, aidleRAM, bidleCPU, bidleRAM, Energy_cost, VMnum;
};

vector<MyServer> mySer;
bool ifdel[maxr] = {false}; //是否已经被删除
vector<int> vm_in_S[maxr]; //在已购买服务器里的虚拟机集合(按顺序序号)

bool cmp2_1(int a, int b){
  return mySer[a].Energy_cost != mySer[b].Energy_cost ? mySer[a].Energy_cost > mySer[b].Energy_cost : mySer[a].VMnum < mySer[b].VMnum;
}

bool cmp2_2(int a, int b){
  return mySer[a].VMnum != mySer[b].VMnum ? mySer[a].VMnum < mySer[b].VMnum :  mySer[a].Energy_cost > mySer[b].Energy_cost;
}

int magic_search(int target_CPU, int target_RAM){
  for(int i=1; i<=N; i++){
    if(ser[i].CPU >= target_CPU && ser[i].RAM >= target_RAM){
      return i;
    }
  }
  return -1;
}

int mov[maxr];
bool vis[maxr], moveend[maxr];

struct Overflow{
  int aCPU, aRAM, bCPU, bRAM;
}pro[maxr];

struct Go{
  int ADDid, Serid, Sernode;
};

void run(){
  for(int i = 0; i <= addindex; ++i){
    mov[i] = i;
  }
  for(int cnt = 1; cnt <= T; ++cnt){
    int purchase=0, migration=0;
    int stid=id; //已经买了多少个服务器
    const int len = task[cnt].n;
    const int TOPmove = getmove(nowadd - nowdel); //当前添加的虚拟机数量和当前删除的虚拟机数量
    vector<Purchase>ansP;
    vector<Migration>ansM;
    vector<CEO>ans;
    unordered_map<string, int>PurchaseSum;
    vector<int>group;
    memset(vis, false, sizeof(vis)); //标记这个服务器是否可迁移
    memset(moveend, false, sizeof(moveend));
    /*填填填买买买*/
    for(int i = 0; i < len; ++i){
      if(task[cnt].a[i] > 0){
        ++nowadd;
        group.emplace_back(task[cnt].a[i]);
        if((i + 1) == len || task[cnt].a[i+1] < 0){ //最后一个请求或者下一个是删除请求, 切割分组
          sort(group.begin(), group.end(), cmp3_1);
          for(auto it = group.begin(); it != group.end(); it++){
            ADD now = add[*it];
            int minCR = INF, p = -1, node = -1;
            if(now.is_Even == 1){
              const int nCPU = now.CPU / 2;
              const int nRAM = now.RAM / 2;
              for(int j = 0; j < myid; ++j){
                if(mySer[j].aidleCPU >= nCPU && mySer[j].aidleRAM >= nRAM && mySer[j].bidleCPU >= nCPU && mySer[j].bidleRAM >= nRAM){
                  int aC = mySer[j].aidleCPU - nCPU;
                  int aR = mySer[j].aidleRAM - nRAM;
                  int bC = mySer[j].bidleCPU - nCPU;
                  int bR = mySer[j].bidleRAM - nRAM;
                  int temp1 = max(aC, bC);
                  int temp2 = max(aR, bR);
                  int temp = max(temp1, temp2);
                  if(temp < minCR){
                    minCR = temp;
                    p = j;
                  }
                }
              }
              if(p != -1){  //找到填的服务器了
                vis[p] = true;
                add[*it].Serid = p;
                add[*it].Sernode = 0;
                mySer[p].aidleCPU -= nCPU;
                mySer[p].aidleRAM -= nRAM;
                mySer[p].bidleCPU -= nCPU;
                mySer[p].bidleRAM -= nRAM;
                ++mySer[p].VMnum;
                vm_in_S[p].emplace_back(*it);
              }else{
                int aim = magic_search(nCPU, nRAM);
                add[*it].Serid = myid;
                add[*it].Sernode = 0;
                vm_in_S[myid].emplace_back(*it);
                mySer.push_back({ser[aim].TYPE, ser[aim].CPU - nCPU, ser[aim].RAM - nRAM, ser[aim].CPU - nCPU, ser[aim].RAM - nRAM, ser[aim].Energy_cost, 1});
                ++myid;
                PurchaseSum[ser[aim].TYPE]++;
#ifdef LOCAL_TEST
                money += ser[aim].Hardware_cost;
                money1 += ser[aim].Hardware_cost;
#endif
              }
            }else{
              const int nCPU = now.CPU;
              const int nRAM = now.RAM;
              for(int j = 0; j < myid; ++j){
                if(mySer[j].aidleCPU >= nCPU && mySer[j].aidleRAM >= nRAM){
                  int aC = mySer[j].aidleCPU - nCPU;
                  int aR = mySer[j].aidleRAM - nRAM;
                  int temp = max(aC, aR);
                  if(temp < minCR){
                    minCR = temp;
                    p = j;
                    node = 1;
                  }
                }
                if(mySer[j].bidleCPU >= nCPU && mySer[j].bidleRAM >= nRAM){
                  int bC = mySer[j].bidleCPU - nCPU;
                  int bR = mySer[j].bidleRAM - nRAM;
                  int temp = max(bC, bR);
                  if(temp < minCR){
                    minCR = temp;
                    p = j;
                    node = 2;
                  }
                }
              }
              if(p != -1){
                vis[p] = true;
                add[*it].Serid = p;
                add[*it].Sernode = node;
                if(node == 1){
                  mySer[p].aidleCPU -= nCPU;
                  mySer[p].aidleRAM -= nRAM;
                }else if(node == 2){
                  mySer[p].bidleCPU -= nCPU;
                  mySer[p].bidleRAM -= nRAM;
                }
                ++mySer[p].VMnum;
                vm_in_S[p].emplace_back(*it);
              }else{
                int aim = magic_search(nCPU, nRAM);
                add[*it].Serid = myid;
                add[*it].Sernode = 2;
                vm_in_S[myid].emplace_back(*it);
                mySer.push_back({ser[aim].TYPE, ser[aim].CPU, ser[aim].RAM, ser[aim].CPU - nCPU, ser[aim].RAM - nRAM, ser[aim].Energy_cost, 1});
                ++myid;
                PurchaseSum[ser[aim].TYPE]++;
#ifdef LOCAL_TEST
                money += ser[aim].Hardware_cost;
                money1 += ser[aim].Hardware_cost;
#endif
              }
            }
          }
        }
      }else{
        ++nowdel;
        group.clear();
        const int deladd = del[(0 - task[cnt].a[i])];
        if((add[deladd].Serid != -1) && !ifdel[deladd]){
          const int freeid = add[deladd].Serid;
          vis[freeid] = true;
          if(add[deladd].is_Even == 1){
            const int nCPU = add[deladd].CPU / 2;
            const int nRAM = add[deladd].RAM / 2;
            mySer[freeid].aidleCPU += nCPU;
            mySer[freeid].aidleRAM += nRAM;
            mySer[freeid].bidleCPU += nCPU;
            mySer[freeid].bidleRAM += nRAM;
          }else{
            const int nCPU = add[deladd].CPU;
            const int nRAM = add[deladd].RAM;
            if(add[deladd].Sernode == 1){
              mySer[freeid].aidleCPU += nCPU;
              mySer[freeid].aidleRAM += nRAM;
            }else if(add[deladd].Sernode == 2){
              mySer[freeid].bidleCPU += nCPU;
              mySer[freeid].bidleRAM += nRAM;
            }
          }
          mySer[freeid].VMnum--;
          ifdel[deladd] = true;
        }
      }
    }
    /*迁字诀*/
#ifdef MIGRATE
    sort(mov, mov + stid, cmp2_2);
    for(int i = 0; i < stid; ++i){
      if(migration >= TOPmove) break;
      const int gosid = mov[i]; //迁出的服务器
      if(vis[gosid] || moveend[gosid]) continue;
      const int nowEnergy_cost = mySer[gosid].Energy_cost;
      if(mySer[gosid].VMnum > 0 && (migration + mySer[gosid].VMnum) < TOPmove){  //有得迁
        priority_queue<GoMOVE>q;
        vector<Go>shift;
        vector<int>eraseindex;
        for(int j = vm_in_S[gosid].size() - 1; j >= 0; --j){
          if(ifdel[vm_in_S[gosid][j]]){
            continue;
          }
          q.push({vm_in_S[gosid][j], add[vm_in_S[gosid][j]].CRSUM, add[vm_in_S[gosid][j]].CPU, add[vm_in_S[gosid][j]].RAM});
          eraseindex.emplace_back(j);
        }
        while(!q.empty()){
          int minCR = INF, p = -1, node = -1;
          int nowmove = q.top().ADDid;
          ADD now = add[nowmove];
          q.pop();
          if(now.is_Even == 1){
            const int nCPU = now.CPU / 2;
            const int nRAM = now.RAM / 2;
            for(int j=stid-1; j > i; j--){
              if(vis[mov[j]]){
                continue;
              }
              const int tosid = mov[j];
              const int leftaCPU = mySer[tosid].aidleCPU - pro[tosid].aCPU;
              const int leftaRAM = mySer[tosid].aidleRAM - pro[tosid].aRAM;
              const int leftbCPU = mySer[tosid].bidleCPU - pro[tosid].bCPU;
              const int leftbRAM = mySer[tosid].bidleRAM - pro[tosid].bRAM;
              if(leftaCPU >= nCPU && leftaRAM >= nRAM && leftbCPU >= nCPU && leftbRAM >= nRAM){
                int aC = leftaCPU - nCPU;
                int aR = leftaRAM - nRAM;
                int bC = leftbCPU - nCPU;
                int bR = leftbRAM - nRAM;
                int temp1 = max(aC, bC);
                int temp2 = max(aR, bR);
                int temp = max(temp1, temp2);
                if(temp < minCR){
                  minCR = temp;
                  p = tosid;
                }
              }
            }
            if(p != -1){
              shift.push_back({nowmove, p, 0});
              pro[p].aCPU += nCPU;
              pro[p].aRAM += nRAM;
              pro[p].bCPU += nCPU;
              pro[p].bRAM += nRAM;
            }else{
              break;
            }
          }else{
            const int nCPU = now.CPU;
            const int nRAM = now.RAM;
            for(int j = stid-1; j > i; j--){
              if(vis[mov[j]]){
                continue;
              }
              const int tosid = mov[j];
              const int leftaCPU = mySer[tosid].aidleCPU - pro[tosid].aCPU;
              const int leftaRAM = mySer[tosid].aidleRAM - pro[tosid].aRAM;
              const int leftbCPU = mySer[tosid].bidleCPU - pro[tosid].bCPU;
              const int leftbRAM = mySer[tosid].bidleRAM - pro[tosid].bRAM;
              if(leftaCPU >= nCPU && leftaRAM >= nRAM){
                int aC = leftaCPU - nCPU;
                int aR = leftaRAM - nRAM;
                int temp = max(aC, aR);
                if(temp < minCR){
                  minCR = temp;
                  p = tosid;
                  node = 1;
                }
              }
              if(leftbCPU >= nCPU && leftbRAM >= nRAM){
                int bC = leftbCPU - nCPU;
                int bR = leftbRAM - nRAM;
                int temp = max(bC, bR);
                if(temp < minCR){
                  minCR = temp;
                  p = tosid;
                  node = 2;
                }
              }
            }
            if(p != -1){
              shift.push_back({nowmove, p, node});
              if(node == 1){
                pro[p].aCPU += nCPU;
                pro[p].aRAM += nRAM;
              }else if(node == 2){
                pro[p].bCPU += nCPU;
                pro[p].bRAM += nRAM;
              }
            }else{
              break;
            }
          }
        }
        if(shift.size() == mySer[gosid].VMnum){ //全部迁出
          for(int k=0, limit = shift.size(); k < limit; ++k){
            ADD now = add[shift[k].ADDid];
            moveend[shift[k].Serid] = true;
            if(now.is_Even == 1){
              const int nCPU = now.CPU / 2;
              const int nRAM = now.RAM / 2;
              mySer[shift[k].Serid].aidleCPU -= nCPU;
              mySer[shift[k].Serid].aidleRAM -= nRAM;
              mySer[shift[k].Serid].bidleCPU -= nCPU;
              mySer[shift[k].Serid].bidleRAM -= nRAM;
              mySer[shift[k].Serid].VMnum++;
              vm_in_S[shift[k].Serid].emplace_back(shift[k].ADDid);
              mySer[gosid].aidleCPU += nCPU;
              mySer[gosid].aidleRAM += nRAM;
              mySer[gosid].bidleCPU += nCPU;
              mySer[gosid].bidleRAM += nRAM;
              mySer[gosid].VMnum--;
              add[shift[k].ADDid].Serid = shift[k].Serid;
              ansM.push_back({addtovmid[shift[k].ADDid], shift[k].Serid, shift[k].Sernode});
            }else{
              const int nCPU = now.CPU;
              const int nRAM = now.RAM;
              if(shift[k].Sernode == 1){
                mySer[shift[k].Serid].aidleCPU -= nCPU;
                mySer[shift[k].Serid].aidleRAM -= nRAM;
              }else if(shift[k].Sernode == 2){
                mySer[shift[k].Serid].bidleCPU -= nCPU;
                mySer[shift[k].Serid].bidleRAM -= nRAM;
              }
              mySer[shift[k].Serid].VMnum++;
              vm_in_S[shift[k].Serid].emplace_back(shift[k].ADDid);
              if(now.Sernode == 1){
                mySer[gosid].aidleCPU += nCPU;
                mySer[gosid].aidleRAM += nRAM;
              }else if(now.Sernode == 2){
                mySer[gosid].bidleCPU += nCPU;
                mySer[gosid].bidleRAM += nRAM;
              }
              mySer[gosid].VMnum--;
              add[shift[k].ADDid].Serid = shift[k].Serid;
              add[shift[k].ADDid].Sernode = shift[k].Sernode;
              ansM.push_back({addtovmid[shift[k].ADDid], shift[k].Serid, shift[k].Sernode});
            }
          }
          for(int k = 0, limit = eraseindex.size(); k < limit; ++k){
            vm_in_S[gosid].erase(vm_in_S[gosid].begin() + eraseindex[k]);
            ++migration;
          }
        }
        for(int k = 0, limit = shift.size(); k < limit; ++k){
          pro[shift[k].Serid].aCPU = pro[shift[k].Serid].aRAM = pro[shift[k].Serid].bCPU = pro[shift[k].Serid].bRAM = 0;
        }
      }
    }
#endif
    /*准备输出答案*/
    for(auto &x:PurchaseSum){
      ansP.push_back({x.first, x.second});
      for(int i=stid; i<myid; i++){ //新买的服务器
        if(mySer[i].TYPE == x.first){
          idhash[i]=id++;
        }
      }
		  purchase++;
    }
    for(int i=0; i<len; ++i){
      if(task[cnt].a[i] > 0){
        ADD now = add[task[cnt].a[i]];
        if(now.Sernode == 1){
          ans.push_back({now.Serid, 1});
        }else if(now.Sernode == 2){
          ans.push_back({now.Serid, 2});
        }else if(now.Sernode == 0){
          ans.push_back({now.Serid, 0});
        }
      }
    }
#ifdef LOCAL_TEST
    for(auto &x : mySer){
      Server now = ser[SerHash[x.TYPE]];
      if(x.aidleCPU == now.CPU && x.bidleCPU == now.CPU && x.aidleRAM == now.RAM && x.bidleRAM == now.RAM){}else{
        money += x.Energy_cost;
      }
    }
#endif
    outputq(ansP, purchase);
    outputw(ansM, migration);
    output(ans);
  }
  return ;
}

int main(){
#ifdef LOCAL_TEST
  auto start = system_clock::now();
#endif
  read();
  run();
#ifdef LOCAL_TEST
  auto endt = system_clock::now();
  auto duration = duration_cast<microseconds>(endt - start);
  fprintf(stderr, "COST: %lld ( HARDWARE ~ %lld ENERGY ~ %lld )\n", money, money1, money - money1);
  fprintf(stderr, "SERVER NUM: %zu\n", mySer.size());
  fprintf(stderr, "TOTAL: %.3f s\n", double(duration.count()) * microseconds::period::num / microseconds::period::den);
#endif
  return 0;
}

四、来年再战

软件精英挑战赛算是我参加过的最好玩的比赛了,只要在学校我决定每年都参加。今年止步64强省下1个月时间给我提前预习考研,也算是好事,明年大四,各种事情尘埃落定,应该可以静下心来全力以赴。如果杭厦赛区有明年想一起冲击4强的兄弟可以联系我,组一支最强阵容来年再战!

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

征服所有不服

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

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

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

打赏作者

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

抵扣说明:

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

余额充值