例如,下面给出了一组移动的例子,例子中学生的人数为8人。
0)初始队列中学生的学号依次为1, 2, 3, 4, 5, 6, 7, 8;
1)第一次调整,命令为“3号同学向后移动2”,表示3号同学出队,向后移动2名同学的距离,再插入到队列中,新队列中学生的学号依次为1, 2, 4, 5, 3, 6, 7, 8;
2)第二次调整,命令为“8号同学向前移动3”,表示8号同学出队,向前移动3名同学的距离,再插入到队列中,新队列中学生的学号依次为1, 2, 4, 5, 8, 3, 6, 7;
3)第三次调整,命令为“3号同学向前移动2”,表示3号同学出队,向前移动2名同学的距离,再插入到队列中,新队列中学生的学号依次为1, 2, 4, 3, 5, 8, 6, 7。
小明记录了所有调整的过程,请问,最终从前向后所有学生的学号依次是多少?
请特别注意,上述移动过程中所涉及的号码指的是学号,而不是在队伍中的位置。在向后移动时,移动的距离不超过对应同学后面的人数,如果向后移动的距离正好等于对应同学后面的人数则该同学会移动到队列的最后面。在向前移动时,移动的距离不超过对应同学前面的人数,如果向前移动的距离正好等于对应同学前面的人数则该同学会移动到队列的最前面。
第二行包含一个整数 m,表示调整的次数。
接下来m行,每行两个整数p, q,如果q为正,表示学号为p的同学向后移动q,如果q为负,表示学号为p的同学向前移动-q。
3
3 2
8 -3
3 -2
对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ m ≤ 1000,所有移动均合法。
本题首先想到使用链表来解决,因为涉及到多次元素的移动和删除,用链表会更加方便一些,下边给出程序:
import java.util.LinkedList;
import java.util.Scanner;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int n;
LinkedList<Integer> list = new LinkedList<Integer>();
n = input.nextInt();
for(int i = 0;i<=n;i++){
list.add(i);
}
int m = input.nextInt();
for(int j = 0;j<m;j++){
int p = input.nextInt();
int q = input.nextInt();
int position = list.indexOf(p);
if(q>=0){
list.remove(position);
list.add(position+q, p);
}else{
list.add(position+q, p);
list.remove(position+1);//前边加了一个,后边的位置相对加1
}
}
for(int i = 1;i<=n;i++){
System.out.print(list.get(i)+" ");
}
}
}