您的位置:首页 > 其它

银行排队问题之单窗口“夹塞”版(pta)

2017-08-14 15:51 375 查看
传送门:
https://pta.patest.cn/pta/test/15/exam/4/question/895
思路:先用并查集确定各个顾客(结点)的父亲,然后依次处理进来的顾客,对每个顾客(A),

找到和他同一个结点的并且离他最近的(B)(输入顺序),看这个结点(B)的开始时间是否小于等于前面顾客的(A)结束时间,

如果是,那这个顾客(B)作为下一个进来的顾客,否则,(除去已经处理过的)最前面的结点作为下一个顾客结点。

在顾客名字的处理上,我借用了map映射,但是map<string,int>这种形式会超时,然后用了map<char*,int>,

在网上查了几篇博客,说要先重载,具体的看下面代码。

我做完后回过头来看到一句话特别有感悟,就是用char*做map参数时,实际参与映射的是指针,而用string时传进去的是一个对象。

所以处理的时候,需要注意一下,具体的还是看下面代码。

1 #include<cstdio>
2 #include<iostream>
3 #include<cstring>
4 #include<map>
5 using namespace std;
6 struct ptrCmp//写一个比较函数,里面重载(),这一段是网上原模原样看过来的
7 {
8 bool operator()(const char*s1,const char*s2)const//结尾有个const,别丢,可能编译过不了
9 {
10 return strcmp(s1,s2)<0;
11 }
12 };
13 map<char*,int,ptrCmp> M;
14 int ant=1;
15 int c=0;
16 int sum=0;
17 int e;
18 int f[10005];
19 int vis[10005]={0};
20 char aa[10005][5];//记住这个,下面看到的时候注意下
21 int Index=0;
22 struct Node
23 {
24 char name[5];
25 int start;
26 int time;
27 }node[10005];
28 void Init(int n)
29 {
30 int i;
31 M.clear();
32 for(i=1;i<=n;i++)
33 {
34 f[i]=i;
35 }
36 }
37 void Insert(char* p)
38 {
39 if(M.count(p)==0)
40 {
//把p所指向的内容赋值给aa中的某一行,不然p其实是同一块地址,那这个循环就只能跑一次
//这里就需要额外的内存空间去表示不同的名字(BOB啊这些),所以用了aa[][]
41 strcpy(aa[Index],p);
42 M[aa[Index]]=ant;
43 Index++;
44 ant++;
45 }
46 }
47 int find(int p)
48 {
49 if(f[p]==p)
50 return p;
51 f[p]=find(f[p]);
52 return f[p];
53 }
54 void dispose(int s)
55 {
56 if(e>=node[s].start)
57 {
58 sum+=e-node[s].start;
59 e+=node[s].time;
60 }
61 else
62 e=node[s].start+node[s].time;
63 cout<<node[s].name<<endl;
64 vis[s]=1;
65 c++;
66 }
67 int find_next(int s,int n)
68 {
69 int i;
70 for(i=1;i<=n;i++)
71 {
72 if(vis[i]==0)
73 {
74 if(f[M[node[s].name]]==f[M[node[i].name]]&&e>=node[i].start)
75 {
76 return i;
77 }
78 }
79 }
80 for(i=1;i<=n;i++)
81 {
82 if(vis[i]==0)
83 return i;
84 }
85 }
86 int main()
87 {
88 int n,m,num,i,j;
89 int start,time;
90 char temp[5];
91 scanf("%d%d",&n,&m);
92 Init(n);
93 while(m--)
94 {
95 scanf("%d",&num);
96 scanf("%s",temp);
97 Insert(temp);
98 int father=find(M[temp]);
99 for(j=2;j<=num;j++)
100 {
101 scanf("%s",temp);
102 Insert(temp);
103 int temp_father=find(M[temp]);
104 if(father!=temp_father)
105 {
106 f[temp_father]=father;
107 }
108 }
109 }
110 for(i=1;i<=n;i++)
111 {
112 scanf("%s%d%d",temp,&start,&time);
113 if(time>60)
114 time=60;
115 strcpy(node[i].name,temp);
116 node[i].start=start;
117 node[i].time=time;
118 }
119 e=node[1].start;
120 int s=1;
121 while(1)
122 {
123 dispose(s);
124 s=find_next(s,n);
125 if(c>=n)
126 break ;
127 }
128 printf("%.1f\n",1.0*sum/n);
129 return 0;
130 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息