UVALive 5789 双向链表解法

Nlogonia is ghting a ruthless war against the neighboring country of Cubiconia. The Chief General of
Nlogonia's Army decided to attack the enemy with a linear formation of soldiers, that would advance
together until conquering the neighboring country. Before the battle, the Chief General ordered that
each soldier in the attack line, besides protecting himself and attacking, should also protect his two
(nearest) neighbors in the line, one to his left and one to his right. The Chief General told the soldiers
that for each of them, his \buddies" would be these two neighbors, if such neighbors existed (because
the leftmost soldier does not have a left neighbor and the rightmost soldier does not have a right
neighbor). The Chief General also told the soldiers that protecting their buddies was very important
to prevent the attack line from being broken. So important that, if the left or right buddy of a soldier
is killed, then the next living neighbor to the left or to the right of the soldier, respectively, should
become his buddy.
The battle is erce, and many soldiers in the attack line are being killed by re shots, grenades and
bombs. But following the Chief General's orders, immediately after knowing about losses in the attack
line, the Army's information systems division has to inform the soldiers who their new buddies are.
You are given the number of soldiers in the attack line, and a sequence of loss reports. Each loss
report describes a group of contiguous soldiers in the attack line that were just killed in the battle.
Write a program that, for each loss report, prints the new buddies formed.
Input
Each test case is described using several lines. The rst input line contains two integers S and B
representing respectively the number of soldiers in the attack line, and the number of loss reports
(1 B S 105
). Soldiers are identi ed by different integers from 1 to S, according to their
positions in the attack line, being 1 the leftmost soldier and S the rightmost soldier. Each of the next
B input lines describes a loss report using two integers L (left) and R (right), meaning that soldiers
from L to R were killed (1 L R S). You may assume that until that moment those soldiers were
alive and were just killed.
The last test case is followed by a line containing two zeros.
Output
For each test case output B + 1 lines. In the i-th output line write the new buddies formed by removing
from the attack line the soldiers that were just killed according to the i-th loss report. That is, for the
loss report `L R', print the rst surviving soldier to the left of L, and the rst surviving soldier to the
right of R. For each direction, print the character `*' (asterisk) if there is no surviving soldier in that
direction. Print a line containing a single character `-' (hyphen) after each test case.
Sample Input
1 1
1 1
10 4
2 5
6 9
1 1
10 10
5 1
1 1
0 0
Sample Output
* *
-
1 6
1 10
* 10
* *
-
* 2

-

题意:

s个士兵排成一列,每次有L到R这些原本健在的士兵死亡,求L-1到1第一个还活着的士兵的编号,以及R+1到s第一个活着的士兵的编号,不存在则输出*。

可以用线段树或并查集做 但我当时使用双向链表做的。


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;


struct mm
{
mm *left,*right;
int num;
}A[100005];
int S,B;
int b,e;


int main()
{
//struct mm *p;
while(cin>>S>>B && S)
{
if(S>1)
{
A[1].num=1;
A[1].left=NULL;
A[1].right=&A[2];

for(int i=2;i<S;i++)
{
A[i].num=i;
A[i].left=&A[i-1];
A[i].right=&A[i+1];
}
A[S].num=S;
A[S].left=&A[S-1];
A[S].right=NULL;
}

else A[1].left=A[1].right=NULL;   //只有一个士兵的情况 

for(int i=0;i<B;i++)
{
scanf("%d%d",&b,&e);
if(A[b].left != NULL) printf("%d ",A[b].left->num);
else printf("* ");
if(A[e].right != NULL) printf("%d\n",A[e].right->num);
else printf("*\n");

if(A[b].left)
A[b].left->right=A[e].right;    //要判断左右指向是否为空 否则出错 
if(A[e].right)
A[e].right->left=A[b].left;
}

cout<<"-"<<endl;
}
return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值