cdoj 2015数据结构专题:D - 秋实大哥与战争

来源:互联网 发布:天猫整站j2ee源码下载 编辑:程序博客网 时间:2024/05/22 12:09

男儿何不带吴钩,收取关山五十州。

征战天下是秋实大哥一生的梦想,所以今天他又在练习一个对战游戏。

秋实大哥命令所有士兵从左到右排成了一行来抵挡敌人的攻击。

敌方每一次会攻击一个士兵,这个士兵就会阵亡,整个阵列就会从这个位置断开;同时有的时候已阵亡的士兵会受人赢气息感染而复活。

秋实大哥想知道某一时刻某一个士兵所在的阵列的长度是多少。

Input

第一行包含两个整数nm,表示秋实大哥的士兵数目和接下来发生的事件数目。

接下来m行,每一行是以下三种事件之一:

0 x : 表示x位置的士兵受到攻击阵亡1 x : 表示x位置的士兵受人赢气息感染复活2 x : 秋实大哥想知道第x个士兵所在阵列的长度

1nm1000001xn

Output

对于每一个2 x事件,输出对应的答案占一行。

Sample input and output

Sample InputSample Output
5 32 20 32 2
52



#include <iostream>#include <cstdio>#include <list>using namespace std;list<int> l;void die(int x){    list<int>::iterator l1,l2;    l2 = l.end();    for(l1 = l.begin();x > *l1 && l1 != l2;l1++);    if(x != *l1)        l.insert(l1, x);}void re(int x){    list<int>::iterator l1,l2;    l2 = l.end();    for(l1 = l.begin();x != *l1 && l1 != l2;l1++);    l.erase(l1);}int main(){    int n,m,x,p;    scanf("%d%d",&n,&m);    l.push_back(0);    l.push_back(n+1);    while(m --){        scanf("%d%d",&p,&x);        if(p == 0)            die(x);        else if(p == 1)            re(x);        else{            list<int>::iterator l1,l2,l3;            l2 = l.end();            for(l1 = l.begin();x > *l1 && l1 != l2;l1++);            if(x == *l1){                printf("0\n");                continue;            }            l3 = l1;            l3 --;            printf("%d\n",*l1 - *l3 - 1);        }    }    return 0;}

list实现(后来发现用set好像更优)。

一共n个士兵,先将0n+1加入链表,当有士兵死亡时,将死亡士兵的位置加入链表,并保证链表按升序排列。当某士兵复活时,从链表中删除该士兵的位置。询问士兵所在阵列长度时,从头至尾遍历链表,找出被询问士兵所在区间,通过两边死亡士兵位置或边界位置相减再减1,得到阵列长度。

需要特别注意加以判断的有两点,一是死亡的士兵还可能被攻击,但是链表中不能再加一个,这种情况在死亡士兵加入链表时加以判断,保证其不在链表中才能加入,否则不加入。另一个是死亡的士兵可能被询问,当死亡士兵被询问时,输出0,故在询问中多加条判断。


0 0
原创粉丝点击