PAT 1016

题目 : Phone Bills

分值 : 25
难度 : 最有价值的题
思路 : 思路一开始我就很清晰,对于每个记录全存进来,然后对name第一关键字time第二关键字
       排序,然后遍历排序之后的同一个人 on-off匹配,筛掉不匹配的项,然后一个遍历。
坑点 : 坑点有点多,不过每个坑点都对应我一直以来的一些盲点,所以我选择一一阐述。 
评语 : 解决方案很容易想到,但是因为需要处理很多细节

第一个知识盲点

一开始代码能跑出例程,但是在pat系统上提交之后全是运行时错误,很不解,后来想出来一个歪招,就是在每一个地方尝试性 #if 0 #endif 然后提交,最终终于找出原来是

1
string old_name = NULL;

string 字符串不可以初始化为NULL,虽然能通过编译,但是出现运行时错误的主因就是这个,其次string也不能和NULL比较,要是用empty()或者==””。

第二个玄学坑

我使用结构体记录数据,结构体内部参数是string型,而我对结构体进行排序时利用的是qsort进行排序,这在很早以前有道题我就发现了,我用qsort进行排序在本地跑的确能够通过,但是在pat上跑总是会出现段错误,其中的问题深究半天没有发现,网上看发现都没有人像我这么傻,用的c++的string还有c的qosrt,为了今后不再继续躺这个坑,我选择使用sort作为我新的排序工具。说实话:相比而言,sort比qsort好用。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <algorithm>   //sort 要用到的头文件 注意要加
typedef struct Node{
string name ;
string tme ;
string kind ;
}Nodes ;
Nodes list[1001];
bool cmp1(Node a, Node b ) // name 第一关键字升序 time第二关键字 升序
{
if( (a.name == b.name )) //我返回的值是一个 bool量 我索性直接 < 来比较
return a.tme < b.tme ; //简单粗暴 使用 a.compare(b) 有条件
else // a.compare(b) a>b:1/ a==b:0 /a<b:-1
return a.name < b.name ;

}
sort(list, list+N ,cmp1); //sort 用起来很方便啊 第一个参数你要排序的 数组首项
//第二个参数排序的数组末项 第三个参数 自定义cmp

具体代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <iostream>
#include <string>
#include <algorithm>
using namespace std ;
typedef struct Node{
string name ;
string tme ;
string kind ;
}Nodes ;
Nodes list[1001];
bool cmp1(Node a, Node b )
{
if( (a.name == b.name ))
return a.tme.compare(b.tme) < 0 ;
else
return a.name .compare(b.name) < 0 ;

}

int data[25] ;
int total =0 ;
int main() {
for (int i = 0; i < 24; i++)
{
cin >> data[i];
total += data[i] ;
}
int N;
cin >> N;
for (int i = 0; i < N; i++) {
cin >> list[i].name >> list[i].tme >> list[i].kind;
}
sort(list, list+N ,cmp1);
//for (int i = 0; i < N; i++) {
// cout<< list[i].name <<" "<< list[i].tme <<" "<< list[i].kind<<endl ;
//}
Nodes result[1002] ;
int cur = 0 ;
int old = 0 ;
#if 1
for(int i = 0; i< N ;i++)
{
if(list[i].name != list[old].name)
{
old = i ;
continue;
}
if(list[i].kind=="off-line" && list[old].kind =="on-line")
{
result[cur++] = list[old ];
result[cur++] = list[i] ;
old = i ;
}
else
{
old = i ;
}
}
#endif

string old_name ;
double heihei = 0 ;

for(int i = 0 ; i+1 < cur ;i+=2 )
{
if(result[i].name != old_name )
{
if(i!=0)
printf("Total amount: $%.2lf\n",heihei);
heihei = 0 ;
old_name = result[i].name ;
cout << result[i].name <<" "<<result[i].tme[0]<<result[i].tme[1]<<endl ;
cout << result[i].tme.substr(3) <<" "<<result[i+1].tme.substr(3)<<" ";


int m1, m2 , h1,h2,d1,d2 ;
m1 = (result[i].tme[9]-'0')*10 +result[i].tme[10]-'0';
h1 = (result[i].tme[6]-'0')*10 +result[i].tme[7] -'0';
d1 = (result[i].tme[3]-'0')*10 +result[i].tme[4] -'0';

m2 = (result[i+1].tme[9]-'0')*10 +result[i+1].tme[10]-'0';
h2 = (result[i+1].tme[6]-'0')*10 +result[i+1].tme[7] -'0';
d2 = (result[i+1].tme[3]-'0')*10 +result[i+1].tme[4] -'0';

int sum = d2*60*24 +h2*60 + m2 - (d1*60*24 +h1*60 + m1);

double sum1 = d1 *total *60 ;
for(int j = 0 ; j< h1 ;j++)
{
sum1 += data[j] *60 ;

}
sum1 += data[h1] *m1 ;
double sum2 = d2 *total *60 ;
for(int j = 0 ; j< h2 ;j++)
{
sum2 += data[j] *60 ;
}
sum2 += data[h2] *m2 ;

printf("%d $%.2lf\n",sum ,(sum2-sum1)/100 ) ;
heihei += (sum2-sum1)/100 ;
}
else
{
cout << result[i].tme.substr(3) <<" "<<result[i+1].tme.substr(3)<<" ";
int m1, m2 , h1,h2,d1,d2 ;
m1 = (result[i].tme[9]-'0')*10 +result[i].tme[10]-'0';
h1 = (result[i].tme[6]-'0')*10 +result[i].tme[7] -'0';
d1 = (result[i].tme[3]-'0')*10 +result[i].tme[4] -'0';

m2 = (result[i+1].tme[9]-'0')*10 +result[i+1].tme[10]-'0';
h2 = (result[i+1].tme[6]-'0')*10 +result[i+1].tme[7] -'0';
d2 = (result[i+1].tme[3]-'0')*10 +result[i+1].tme[4] -'0';

int sum = d2*24*60 +h2*60 + m2 - (d1*24*60 +h1*60 + m1);

double sum1 = d1 *total *60 ;
for(int j = 0 ; j< h1 ;j++)
{
sum1 += data[j] *60 ;

}
sum1 += data[h1] *m1 ;
double sum2 = d2 *total *60 ;
for(int j = 0 ; j< h2 ;j++)
{
sum2 += data[j] *60 ;
}
sum2 += data[h2] *m2 ;
printf("%d $%.2lf\n",sum ,(sum2-sum1)/100 ) ;
heihei += (sum2-sum1)/100;
}

}printf("Total amount: $%.2lf\n",heihei);

return 0 ;
}