PAT 乙级 1037

题目

题目地址:https://pintia.cn/problem-sets/994805260223102976/problems/994805284923359232

 

题解

    本题有两个版本的代码,初版因为种种问题写得比较繁琐,具体的分析见后文,更新的之后的版本相对来说要好很多,代码也比较清晰简洁。

    初版的代码主要有如下几方面的问题:

        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的时候看到过很多次,当时还不能很清楚地理解;形参传入后仍然只是一个局部变量,函数内开的一切变量作用范围都只在函数中,一旦函数调用结束,当前存在函数变量中的数据都随函数的调用结束一并被清除;

         解决方式有几种,一是调用结束后将数据返回,二是采用全局变量,三是以引用的方式传参,这里选择第三种方式有效地解决了这一问题。

扫描二维码关注公众号,回复: 2840555 查看本文章

    更新之后的代码相对而言简洁得多,思路是把所有输入数据全部转化为最小进制的单位,相减之后再化回不同的单位。

代码

 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 }

猜你喜欢

转载自www.cnblogs.com/moujun1001/p/9498278.html