STL(vector、set、map)----hdu4585

来源:互联网 发布:韩国rap知乎 编辑:程序博客网 时间:2024/06/04 18:35

Shaolin

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 659    Accepted Submission(s): 310


Problem Description
Shaolin temple is very famous for its Kongfu monks.A lot of young men go to Shaolin temple every year, trying to be a monk there. The master of Shaolin evaluates a young man mainly by his talent on understanding the Buddism scripture, but fighting skill is also taken into account.
When a young man passes all the tests and is declared a new monk of Shaolin, there will be a fight , as a part of the welcome party. Every monk has an unique id and a unique fighting grade, which are all integers. The new monk must fight with a old monk whose fighting grade is closest to his fighting grade. If there are two old monks satisfying that condition, the new monk will take the one whose fighting grade is less than his.
The master is the first monk in Shaolin, his id is 1,and his fighting grade is 1,000,000,000.He just lost the fighting records. But he still remembers who joined Shaolin earlier, who joined later. Please recover the fighting records for him.
 

Input
There are several test cases.
In each test case:
The first line is a integer n (0 <n <=100,000),meaning the number of monks who joined Shaolin after the master did.(The master is not included).Then n lines follow. Each line has two integer k and g, meaning a monk's id and his fighting grade.( 0<= k ,g<=5,000,000)
The monks are listed by ascending order of jointing time.In other words, monks who joined Shaolin earlier come first.
The input ends with n = 0.
 

Output
A fight can be described as two ids of the monks who make that fight. For each test case, output all fights by the ascending order of happening time. Each fight in a line. For each fight, print the new monk's id first ,then the old monk's id.
 

Sample Input
32 13 34 20
 

Sample Output
2 13 24 2
 

Source
2013ACM-ICPC杭州赛区全国邀请赛
 
 
试着用vector、set、map(都是初学的)去解决hdu4585。结果显然是不同的,所以在这里记录下。
 
vector+struct
#include<stdio.h>#include<vector>#include<iostream>#include<algorithm>#include<set>#include<string.h>#include<time.h> #include <stdlib.h>#define N 100010using namespace std;typedef struct {int idn,degree;}node;bool cmp2(node a,node b){return a.degree<b.degree;}vector<node> un;int main(){int n;clock_t begin,end;double y,f=0;begin=clock();freopen("out.txt","r",stdin);while(scanf("%d",&n)!=EOF){if(!n)break;cout<<n<<endl;un.clear();node te;te.idn=1,te.degree=1000000000;un.push_back(te);vector<node>::iterator it;node x;node t;int i,j,k;while(n--){scanf("%d%d",&t.idn,&t.degree);//printf("%d ",t.idn);it=lower_bound(un.begin(),un.end(),t,cmp2);if(it==un.end()){//printf("%d\n",un.back());;}else if(it==un.begin()){//printf("%d\n",un[0].idn);;}else{x=*it;k=it-un.begin()-1;if(x.degree-t.degree<t.degree-un[k].degree)//printf("%d\n",x.idn);;else//printf("%d\n",un[k].idn);;}begin=clock();un.insert(it,t);end=clock();f+=(end-begin);if(n%1000==0){end=clock();y=end-begin;//printf("%lf\n",y);}//for(j=0;j<un.size();j++)//printf("%d %d_",un[j].idn,un[j].degree);//printf("\n");}}//cout<<n<<endl;printf("%lf\n",f);}

运行结果是超时的,后来自己编数据用clock测时了下(13s),发现是vector附带的insert函数时间消耗(11s)太大了(多谢kuangbin的指教)。(lower_bound函数的4个参数形式以后可能用的到,以及clock的测时以后比赛 自己以后要学会灵活使用)。
 
 
 
vector+map:
#include<iostream>#include<stdio.h>#include<vector>#include<map>#include<algorithm>#include<time.h>using namespace std;vector<int> num;map<int,int>mp;bool cmp(int a,int b){return a<b;}int main(){int n;//clock_t st,en;//double all=0;//freopen("out.txt","r",stdin);while(scanf("%d",&n),n){num.clear();mp.clear();//num.reserve(1000000001);num.push_back(1000000000);mp[1000000000]=1;vector<int>::iterator it;int idn,deg;while(n--) {scanf("%d%d",&idn,°);printf("%d ",idn);it=lower_bound(num.begin(),num.end(),deg);mp[deg]=idn;//printf("————:%d  %d\n",it-num.begin(),*it);if(it==num.begin()){printf("%d\n",mp[*it]);//;}else if(it==num.end()){printf("%d\n",mp[num.back()]);//;}else{int k=*it,f;it--;f=*it;it++;if(k-deg<deg-f)printf("%d\n",mp[k]);//;else printf("%d\n",mp[f]);//;}//st=clock();num.insert(it,deg);//en=clock();//all+=(en-st);}//printf("%lf\n",all);}}
结果仍然是超时的(),原因还是insert函数。但是现在超时1s左右。(不知道是不是结构体比整型耗时多?)

set+map
 
#include<stdio.h>#include<iostream> #include<set>#include<map>using namespace std;set<int> num;map<int,int> mp;void printfset(set<int> n){set<int>::iterator it; for(it=n.begin();it!=n.end();it++){cout<<*it<<" ";}cout<<endl;}int main(){int n;//freopen("in.txt","r",stdin);while(scanf("%d",&n),n){int i,j,k;/*for(i=0;i<10;i++){num.insert(i);num.insert(i+100);}printfset(num);*/num.clear();mp.clear();num.insert(1000000000);mp[1000000000]=1;set<int>::iterator it;int idn,degree;while(n--){scanf("%d%d",&idn,°ree);printf("%d ",idn);it=num.lower_bound(degree);k=*it;if(it==num.end()){it--;printf("%d\n",mp[*it]);} else if(it==num.begin()) {printf("%d\n",mp[*it]);}else {j=*(--it);if(degree-j<=k-degree)printf("%d\n",mp[j]);else printf("%d\n",mp[k]);}num.insert(degree);mp[degree]=idn;}}}

是可以Ac的,set默认自己是升序排列的。insert函数消耗比较少,并且自带lower_bound函数。
 
 
map
#include<iostream>#include<stdio.h>#include<map>#include<algorithm> using namespace std;map<int,int> mp;int main(){int n;while(scanf("%d",&n),n){mp.clear();mp[1000000000]=1;int idn,deg;map<int,int>::iterator it;while(n--){scanf("%d%d",&idn,°);printf("%d ",idn);it=mp.lower_bound(deg);if(it==mp.begin()){printf("%d\n",it->second);}else if(it==mp.end()){it--;printf("%d\n",it->second);}else {int k=it->first;it--;//printf("tt :%d %d",mp[k],mp[it->first]);if(k-deg<deg-it->first)printf("%d\n",mp[k]);else printf("%d\n",mp[it->first]);}mp[deg]=idn;}}}

AC且用时更少,mp用2个参数包含了id和level,使用自己的lower_bound函数。
 
 
总结,vector、set、map作用和性能要熟悉,不然结果对仍很可能超时。
注:合理使用工具更能帮助算法发挥威力!
 
 
 
原创粉丝点击