发布于 

网易雷火0422游戏研发2飞机题解

觉得有空应该好好学一学DP…
↓一个有点繁琐的工程题,呜呜,很好,我最喜欢工程题了!
第三题第四题感觉希望不大遂美美写了个漂亮结构用于自我欣赏(

#include <iostream>
class outJob
{
public:
int ID = -1; //-1 for invalid
int planeNum = 0;
bool working = 1; // 1 for out, 0 for sleep
outJob() {}
outJob(int id, int NUM) : ID(id), planeNum(NUM), working(1) {}
};

class jobQueue
{
public:
outJob data[30000];
int head = 0;
int tail = 0;

void enqueue(outJob x) { data[tail++] = x; }
void dequeue() { head++; }
bool isEmpty() { return (tail == head); }
outJob* queuehead() { return &data[head]; }

void switchJob(int id)
{
for (int i = head; i < tail; i++)
if (id == data[i].ID)
data[i].working = 0;
}

int clearJob() // return sum
{
int tmp = 0, i;
for (i = head; i < tail; i++)
{
if (data[i].working)
{
head = i; // i<index 全部出队 改变队头
return tmp;
}
tmp += data[i].planeNum;
}
head = i;
return tmp;
}
};

int c, n, okplanes;
jobQueue waitingList, outJobList;

int tryOut(outJob x)
{
int id = x.ID, num = x.planeNum;
// printf("--try out ID = %d, NUM = %d--\n", id, num);

int newOut = 0;
// printf("OKplanes = %d, Cplanes = %d\n", okplanes, c);

if (num <= c) // 要派出去的<=总数
{
if (num <= okplanes) // 也<=可用数
{
okplanes -= num, newOut = num;
outJobList.enqueue(x);
// printf("Outjob: %d, %d\n", id, num);
}
}
else // 要派出去的>总数
{
if (okplanes == c) // == 可以升级
{
c = num, okplanes = 0, newOut = num;
outJobList.enqueue(x);
// printf("Upgrade&Outjob: %d, %d\n", id, num);
}
}
// if (!newOut)
// printf("After: OKplanes = %d, Cplanes = %d\n", okplanes, c);
return newOut;
}

int main()
{
while (~scanf("%d %d", &c, &n))
{
okplanes = c;
for (int i = 0; i < n; ++i)
{
int newOut = 0;
int a, b; // a是指令类型,b是指令内容 >1(id) + num or -1 + id
scanf("%d %d", &a, &b);
outJob newJob(a, b);

if (a >= 0) // 派遣任务,编号为a,派遣b台无人机
{
newOut = tryOut(newJob);
if (!newOut)
waitingList.enqueue(newJob);
}
else // 召回任务
{
// printf("--try back ID = %d--\n", b);
outJobList.switchJob(b); // 转换为休眠状态
okplanes += outJobList.clearJob(); // 唤醒连续休眠飞机
// 检查派遣队列
while (1)
{
if (waitingList.isEmpty())
break;
int tp = tryOut(*waitingList.queuehead());
if (tp == 0) // 派遣失败
break;
newOut += tp, waitingList.dequeue(); // 派遣成功
}
}

printf("%d\n", newOut);
// printf("---------\n");
}
}
}