Problem A Problem ID:1000
题意:共有编号为1-400的房间,400个房间分布在一条走廊的两边,从左到右按编号大小依次排开,且1和2相对,3和4相对,依次类推。现从一个房间往另一个房间搬板凳,走廊很窄,同一段走廊只能同时允许一个板凳通过。从一个房间搬到另一房间需要10分钟。问:按要求全部搬完最少需要多长时间?
解题思路形成过程:先对输入的数据进行排序(可用STL容器自动完成),然后在循环中将能同时搬桌子(即符合要求)的房间分成小组,与此同时计算时间,则可得最短时间。
感想:在解决问题的过程中遇到了多个困难。所耗时间最长且最大的两个收获如下:
1:最后经查资料得:.erase()对于vector来说返回值是下一个位置的迭代器,而对于map和set返回值是void,即当某迭代器指向的位置erase()后,原迭代器失效。可以采用后加,即map.erase(iterator++);的方式既删除了所指向的内容,又使得迭代器指向了下一个位置。
2:问题要分析完整,情况必须考虑全面,不能只是专注于写代码和各种检测,而是仔细思考题目,对问题和出现的输出错误分析透彻。
代码:
#include<iostream>
#include<map>
using namespace std;
int main()
{
int m;
cin>>m;
while(m--){
int n,t=0;
map <int,int> s;
map <int,int>::iterator si,sii,siii;
cin>>n;
while(n--){
int p,q,temp;
cin>>p>>q;
if(p>q) //注意细节处理,当输入的一组数据第一个数比第二个大时要交换。
{
temp=p;
p=q;
q=temp;
}
s[p]=q;
}
for(si=s.begin();si!=s.end();){
siii=si;
siii++;
int ff=si->second; //必须的一步,必须对当前最大的值进行保存。
if(siii==s.end()) {t+=10; break;}
for(sii=si;sii!=s.end();){
if(sii==si) ++sii;
if(sii->first>ff&&!(sii->first-ff==1&&sii->first%2==0)) //分析清楚,不要漏条件。
{ff=sii->second;
s.erase(sii++);} //对于map来说,s.erase(sii)不会返回下一个迭代器的地址,可以用sii++的方式进行处理。
else
++sii;
}
s.erase(si++); //同上。
t+=10;
}
s.clear();
cout<<t<<endl;
}
return 0;
}