题目
题目地址:PAT 乙级 1037
题解
本题有两个版本的代码,初版因为种种问题写得比较繁琐,具体的分析见后文,更新的之后的版本相对来说要好很多,代码也比较清晰简洁。
初版的代码主要有如下几方面的问题:
1. 代码繁琐,把简单的问题复杂化。
2. 刷题一直在用C++,虽说C和C++相似,但是思路一直在框定在C++的范围内,不够灵活。
下面就具体代码进行分析:
代码
1 #include <iostream>
2 #include <string>
3 #include <cmath>
4 using namespace std;
5
6 struct Data {
7 string str;
8 int g;
9 int s;
10 int k;
11 int Q;
12 };
13
14 int str2int(string s) {
15 int num = 0;
16 int cnt = 0;
17 for (int i = s.size() - 1; i >= 0; i--) {
18 num += (int(s[i]) - 48) * pow(10, cnt);
19 cnt++;
20 }
21 return num;
22 }
23
24 void str2num(Data &s) {
25 int cnt = 0, loc = 0;
26 for (int i = 0; i < s.str.size(); i++) {
27 string tmp;
28 if (s.str[i] == '.' && cnt == 0) {
29 tmp = s.str.substr(0, i);
30 s.g = str2int(tmp);
31 loc = i;
32 cnt++;
33 }
34 else if (s.str[i] == '.' && cnt == 1) {
35 tmp = s.str.substr(loc + 1, i - loc - 1);
36 s.s = str2int(tmp);
37 loc = i;
38 cnt++;
39 }
40 else if (i == s.str.size() - 1) {
41 tmp = s.str.substr(loc + 1, i - loc);
42 s.k = str2int(tmp);
43 loc = i;
44 }
45 }
46 }
47
48 void compare(Data &a, Data &b) {
49 a.Q = 0;
50 b.Q = 0;
51 if (a.g > b.g)
52 a.Q += 5;
53 else if (a.g < b.g)
54 b.Q += 5;
55 if (a.s > b.s)
56 a.Q += 3;
57 else if (a.s < b.s)
58 b.Q += 3;
59 if (a.k > b.k)
60 a.Q++;
61 else if (a.k < b.k)
62 b.Q++;
63 }
64
65 int main() {
66 Data P, A;
67 cin >> P.str >> A.str;
68 str2num(P);
69 str2num(A);
70 compare(P, A);
71 int g = 0, s = 0, k = 0;
72 if (P.Q < A.Q) {
73 if (A.k >= P.k)
74 k = A.k - P.k;
75 else {
76 A.s--;
77 A.k += 29;
78 k = A.k - P.k;
79 }
80 if (A.s >= P.s)
81 s = A.s - P.s;
82 else {
83 A.g--;
84 A.s += 17;
85 s = A.s - P.s;
86 }
87 g = A.g - P.g;
88 }
89 else {
90 if (P.k >= A.k)
91 k = P.k - A.k;
92 else {
93 P.s--;
94 P.k += 29;
95 k = P.k - A.k;
96 }
97 if (P.s >= A.s)
98 s = P.s - A.s;
99 else {
100 P.g--;
101 P.s += 17;
102 s = P.s - A.s;
103 }
104 g = -(P.g - A.g);
105 }
106 cout << g << "." << s << "." << k << endl;
107
108 return 0;
109 }
1. 在接收输入数据时,使用string接收数据,之后再进行一系列转化,最后才能得到int类型的数据,这个过程就很“笨拙”;因为输入的格式固定,所以如果使用C语言的scanf的格式控制符,就可以极大地简化数据接收部分的代码;
2. 同时在写代码过程中,帮助我理清了一个问题,也是我一直忽视的一个点:结构体在函数内部对数据的操作不能赋给主函数中的实参,现在想来也是很简单的一个问题,函数内部的变量只是局部变量,这句话在学C的时候看到过很多次,当时还不能很清楚地理解;形参传入后仍然只是一个局部变量,函数内开的一切变量作用范围都只在函数中,一旦函数调用结束,当前存在函数变量中的数据都随函数的调用结束一并被清除;
解决方式有几种,一是调用结束后将数据返回,二是采用全局变量,三是以引用的方式传参,这里选择第三种方式有效地解决了这一问题。
更新之后的代码相对而言简洁得多,思路是把所有输入数据全部转化为最小进制的单位,相减之后再化回不同的单位。
代码
1 #include <iostream>
2 #include <cstdio>
3 using namespace std;
4
5 int main() {
6 int g1 = 0, s1 = 0, k1 = 0;
7 int g2 = 0, s2 = 0, k2 = 0;
8 scanf("%d.%d.%d %d.%d.%d", &g1, &s1, &k1, &g2, &s2, &k2);
9 long cnt1 = 0, cnt2 = 0;
10 cnt1 = (g1 * 17 + s1) * 29 + k1;
11 cnt2 = (g2 * 17 + s2) * 29 + k2;
12 long tmp = cnt2 - cnt1;
13 if (tmp < 0) {
14 printf("-");
15 tmp = -tmp;
16 }
17 int g = 0, s = 0, k = 0;
18 g = tmp / 17 / 29;
19 s = (tmp - g * 17 * 29) / 29;
20 k = tmp - g * 17 * 29 - s * 29;
21 printf("%d.%d.%d\n", g, s, k);
22
23 return 0;
24 }
来源:https://www.cnblogs.com/moujun1001/p/9498278.html