试题编号: | 201703-2 |
试题名称: | 学生排队 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: |
问题描述 体育老师小明要将自己班上的学生按顺序排队。他首先让学生按学号从小到大的顺序排成一排,学号小的排在前面,然后进行多次调整。一次调整小明可能让一位同学出队,向前或者向后移动一段距离后再插入队列。
输入格式 输入的第一行包含一个整数n,表示学生的数量,学生的学号由1到n编号。 输出格式 输出一行,包含n个整数,相邻两个整数之间由一个空格分隔,表示最终从前向后所有学生的学号。
样例输入 8 样例输出 1 2 4 3 5 8 6 7 评测用例规模与约定 对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ m ≤ 1000,所有移动均合法。 |
问题解析:
方法一是网上贴的代码,由于隔得时间长了点,忘了加链接。。。
- 方法一思路:先控制移动方向,然后传递步长。v[i] = j; 表示i队列中的位置,j表示队列i位置对应的id是j;
- mpos[i] = j; i表示id,mpos表示i = id的位置j;
# include<iostream>
# include<cstdio>
# include<cstdlib>
# include<cstring>
# include<string>
# include<cmath>
# include<algorithm>
using namespace std;
int v[1010],mpos[1010];//v用来记录位置,mpos用来记录id对应的位置
void mov(int pos,int len,int stp)
{
int tmp = v[pos];//temp = 3
while(len)
{
v[pos] = v[pos+stp];//v[3] = 4;v[4] = 5;
mpos[v[pos]] = pos;//mpos[4] = 3;mpos[5] = 4
pos+=stp;//pos = 4;pos=5;
len--;//2 1
}
v[pos] = tmp;//mpos[3]=5;
mpos[tmp] = pos;//v[5]=3;
}
int main()
{
int n,m;
cin >> n >> m;
for(int i = 1;i <= n;++i)
{
mpos[i] = i;
v[i] = i;
}
while(m--)
{
int id,val;
cin >> id >> val;
int pos = mpos[id];
val<0 ? mov(pos,-val,-1) : mov(pos,val,1);
}
for(int i=1;i<=n;++i)
cout<<v[i]<<" ";
return 0;
}
- 方法2:
- 这一种方法是按队列的方法来,先删除,再插入
# include<iostream>
# include<vector>
using namespace std;
int n,m;
vector<int>v;
vector<int>::iterator it;
int main()
{
std::ios::sync_with_stdio(false);
cin >> n >> m;
for(int i = 0;i < n;++i)
{
v.push_back(i+1);
}
while(m--)
{
int id,val;
cin >> id >> val;
for(it = v.begin();it != v.end();++it)
{
if(*it == id)
{
it = v.erase(it);
/*
*vector循环删除的时候,erase(it)会返回下一个迭代器的地址,保险的做法是赋值给it,
即it= erase(it),这是vector的内部机制所造成的,所以对vector进行erase的时候特别注意迭代器是否会失效!
*/
v.insert(it+val,id);
break;
}
}
}
for(int i = 0;i < v.size();++i)
{
cout << v[i] << " ";
}
cout << endl;
return 0;
}