题目地址如下
AC代码(选测试平台g++,我用vs2010写的,还未优化,):
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std ;
int n , m ;
struct cust
{
int come_no;
int int_name ;
int T ;
int P ;
};
int str2int(char name[])
{
return (name[0]-'A' + 1) * 27 * 27 +
(name[1]-'A' + 1) * 27 +
(name[2]- 'A' + 1) ;
}
char* int2str(int num)
{
char* name2 = (char*)malloc(sizeof(char)*4);
int a = num / (27*27) ;
int b = num / 27 - a*27;
int c = num % 27 ;
name2[0] = a + 'A' - 1 ;
name2[1] = b + 'A' - 1 ;
name2[2] = c + 'A' - 1 ;
name2[3] = '\0' ;
return name2;
}
map<int , int> fri_no ;
vector<cust> vv;
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
int i, L;
char name[4];
for(i=1;i<=m;i++)
{
scanf("%d",&L);
while(L--)
{
scanf("%s",name);
int int_name = str2int(name);
fri_no[int_name] = i ;
}
}
int first_time = 0 ;
cust ctmp ;
for(i=1;i<=n;i++)
{
scanf("%s %d %d", name , &ctmp.T,&ctmp.P) ;
if(ctmp.P > 60) //时间处理
ctmp.P = 60 ;
ctmp.int_name = str2int(name) ; // 字符串name转换成int型name
ctmp.come_no = i ;
if(i == 1 ) // 第一位顾客不用等待
{
first_time = ctmp.T ;
ctmp.T = 0 ;
}else{
ctmp.T -= first_time ;
}
vv.push_back(ctmp) ;
}
int out_count = 0; //完成服务的顾客数目
int pre_out_int_name ; // 上一个服务顾客的int_name
int now_time = 0 ; // 当前时刻
int total_wait_time = 0 ;//总共的等待时间
while(out_count < n)
{
if(out_count == 0)
{
cust now_cust = vv.at(0);
vv.erase(vv.begin());
pre_out_int_name = now_cust.int_name ;
total_wait_time = 0 ;
now_time = now_cust.T + now_cust.P ;
}else{
int tmp_fri_num = fri_no[pre_out_int_name] ; //朋友圈编号
int place = 0;
cust next_cust = vv.at(0);
for(int j = 0 ;j < (int)vv.size() ; j ++)
{
cust cust_tmp = vv.at(j) ;
int cust_tmp_fri_num = fri_no[cust_tmp.int_name];
if(cust_tmp.T <= now_time && cust_tmp_fri_num == tmp_fri_num && tmp_fri_num != 0)
{
next_cust = cust_tmp ;
place = j ;
break;
}
}
vv.erase(vv.begin() + place) ; //删除已经服务的顾客
if(next_cust.T > now_time) //如果 到达时间 大于 当前时间
{
now_time = next_cust.T + next_cust.P ;
total_wait_time += 0;//next_cust.T ; 这里不用等待
}else{
total_wait_time += (now_time - next_cust.T);
now_time += next_cust.P ;
}
pre_out_int_name = next_cust.int_name ;
}
out_count++;
printf("%s\n",int2str(pre_out_int_name)); //顺序打印名字
}
printf("%.1f\n",(1.0*total_wait_time)/n);
return 0 ;
}
思路: 此题是个模拟题,所以刚开始应该是纸上模拟下,看看自己能否把题目测试的例子给完成
(可以调用下 windows calc / linux bc命令,用计算机帮个忙)
接着开始编码了:
对于人名的字符串可以采用 转int型处理,这样方便,我写了两个函数
对于属于同一组的,采用map(没有的map值为0)
然后采用了while 来模拟时间
很遗憾,自己错了几次,也是发现问题的过程,充分发现自己有时候考虑有点不全
注意点:
1 第一个人 不用等待,等待时间大于当前时间,也不用等待
2 题目已经明确了输入,输出。。
3 就是个人思考问题了,题目不难,好像类似这种题的很多,有些还很难。
23分的:
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std ;
int n , m ;
struct cust
{
int come_no;
int int_name ;
int T ;
int P ;
};
int str2int(char name[])
{
return (name[0]-'A' + 1) * 27 * 27 +
(name[1]-'A' + 1) * 27 +
(name[2]- 'A' + 1) ;
}
char* int2str(int num)
{
char* name2 = (char*)malloc(sizeof(char)*4);
int a = num / (27*27) ;
int b = num / 27 - a*27;
int c = num % 27 ;
name2[0] = a + 'A' - 1 ;
name2[1] = b + 'A' - 1 ;
name2[2] = c + 'A' - 1 ;
name2[3] = '\0' ;
return name2;
}
map<int , int> fri_no ;
vector<cust> vv;
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
int i, L;
char name[4];
for(i=1;i<=m;i++)
{
scanf("%d",&L);
while(L--)
{
scanf("%s",name);
int int_name = str2int(name);
fri_no[int_name] = i ;
}
}
cust ctmp ;
for(i=1;i<=n;i++)
{
scanf("%s %d %d", name , &ctmp.T,&ctmp.P) ;
if(ctmp.P > 60)
ctmp.P = 60 ;
ctmp.int_name = str2int(name) ;
ctmp.come_no = i ;
vv.push_back(ctmp) ;
}
int out_count = 0; //完成服务的顾客数目
int pre_out_int_name ; // 上一个服务顾客的int_name
int now_time = 0 ; // 当前时刻
int total_wait_time = 0 ;//总共的等待时间
while(out_count < n)
{
if(out_count == 0)
{
cust now_cust = vv.at(0);
vv.erase(vv.begin());
pre_out_int_name = now_cust.int_name ;
total_wait_time += now_cust.T ;
now_time = now_cust.T + now_cust.P ;
}else{
int tmp_fri_num = fri_no[pre_out_int_name] ;
int place = 0;
cust next_cust = vv.at(0);
for(int j = 0 ;j < (int)vv.size() ; j ++)
{
cust cust_tmp = vv.at(j) ;
if(cust_tmp.T < now_time && fri_no[cust_tmp.int_name] == tmp_fri_num)
{
next_cust = cust_tmp ;
place = j ;
break;
}
}
vv.erase(vv.begin() + place) ; //删除已经服务的顾客
if(next_cust.T > now_time)
{
now_time = next_cust.T + next_cust.P ;
total_wait_time += next_cust.T ;
}else{
total_wait_time += (now_time - next_cust.T);
now_time = now_time + next_cust.P ;
}
pre_out_int_name = next_cust.int_name ;
}
out_count++;
printf("%s\n",int2str(pre_out_int_name)); //顺序打印名字
}
printf("%.1f\n",1.0*total_wait_time/n);
return 0 ;
}
28分的
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std ;
int n , m ;
struct cust
{
int come_no;
int int_name ;
int T ;
int P ;
};
int str2int(char name[])
{
return (name[0]-'A' + 1) * 27 * 27 +
(name[1]-'A' + 1) * 27 +
(name[2]- 'A' + 1) ;
}
char* int2str(int num)
{
char* name2 = (char*)malloc(sizeof(char)*4);
int a = num / (27*27) ;
int b = num / 27 - a*27;
int c = num % 27 ;
name2[0] = a + 'A' - 1 ;
name2[1] = b + 'A' - 1 ;
name2[2] = c + 'A' - 1 ;
name2[3] = '\0' ;
return name2;
}
map<int , int> fri_no ;
vector<cust> vv;
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
int i, L;
char name[4];
for(i=1;i<=m;i++)
{
scanf("%d",&L);
while(L--)
{
scanf("%s",name);
int int_name = str2int(name);
fri_no[int_name] = i ;
}
}
int first_time = 0 ;
cust ctmp ;
for(i=1;i<=n;i++)
{
scanf("%s %d %d", name , &ctmp.T,&ctmp.P) ;
if(ctmp.P > 60)
ctmp.P = 60 ;
ctmp.int_name = str2int(name) ; // 字符串name转换成int型name
ctmp.come_no = i ;
//if(i == 1 ) // 第一位顾客不用等待
//{
// first_time = ctmp.T ;
// ctmp.T = 0 ;
//}else{
// ctmp.T -= first_time ;
//}
vv.push_back(ctmp) ;
}
int out_count = 0; //完成服务的顾客数目
int pre_out_int_name ; // 上一个服务顾客的int_name
int now_time = 0 ; // 当前时刻
int total_wait_time = 0 ;//总共的等待时间
while(out_count < n)
{
if(out_count == 0)
{
cust now_cust = vv.at(0);
vv.erase(vv.begin());
pre_out_int_name = now_cust.int_name ;
total_wait_time = 0 ;
now_time = now_cust.T + now_cust.P ;
}else{
int tmp_fri_num = fri_no[pre_out_int_name] ; //朋友圈编号
int place = 0;
cust next_cust = vv.at(0);
for(int j = 0 ;j < (int)vv.size() ; j ++)
{
cust cust_tmp = vv.at(j) ;
int cust_tmp_fri_num = fri_no[cust_tmp.int_name];
if(cust_tmp.T <= now_time && cust_tmp_fri_num == tmp_fri_num && tmp_fri_num != 0)
{
next_cust = cust_tmp ;
place = j ;
break;
}
}
vv.erase(vv.begin() + place) ; //删除已经服务的顾客
if(next_cust.T > now_time) //如果 到达时间大于 当前时间
{
now_time = next_cust.T + next_cust.P ;
total_wait_time += next_cust.T ;
}else{
total_wait_time += (now_time - next_cust.T);
now_time += next_cust.P ;
}
pre_out_int_name = next_cust.int_name ;
}
out_count++;
printf("%s\n",int2str(pre_out_int_name)); //顺序打印名字
}
printf("%.1f\n",(1.0*total_wait_time)/n);
return 0 ;
}