紫書_例5-10 UVa207

  細節較多,自己寫的第一份半殘品,未能AC,后參考了劉老師的代碼,寫出了第二份的代碼,經過多次修改后總算AC,然而後果也很嚴重,導致代碼和劉老師極其相似,這也是我不喜歡看了參考代碼后再自己寫的緣故。

祇爲怕自己忘記,所以寫博客留檔

1:一開始沒看題,就看劉老師的描述,我以爲輸入的選手信息沒有規定格式,所以第一份寫了找第一個數字的函數來確定名字與成績的分界綫,后看(翻譯)了題目才知道對輸入是有規範的,并且udebug的隨機數據的名字用P+數字描述,讓我寫的讀取信息的一系列操作作廢了;

2:即使看描述,也把劉老師說的很多細節忽略了,後來看到書上都有講,真是弱智了:

No1,對選手的排名,是至少有兩名獲得獎金的并列情況才加'T';

No2,輸出的選手信息不包括沒晉級的,一開始我把全部選手都輸出了。。。;

No3,獎金是順延的,并不是第二名打星,第三名還是拿第三名的獎金,而是第三名拿第二名的獎金;

No4,排序時候,若總分相同,則按照名字的字典序排序;

3:題目在獎金上面的測試數據不需要+eps來解決精度問題,反而隨機數據裏面會出現精度問題;

4:udebug隨機數據不符合劉老師的描述,所以劉老師的代碼不能跑隨機數據;

自己的和劉老師的代碼都貼出來==兩個雖然長得很像

我的代碼:

  1 #define _CRT_SECURE_NO_WARNINGS
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<algorithm>
  5 #include<string>
  6 #include<cstring>
  7 #include<cctype>
  8 #include<utility>
  9 #include<cassert>
 10 #include<cmath>
 11 using namespace std;
 12 
 13 #define FOR(i,n) for(int i=0;i<(n);i++)
 14 
 15 const int maxn = 144;
 16 const int n_cut = 70;
 17 double eps = 1e-6;
 18 double money[n_cut], totle;
 19 int n;
 20 
 21 struct Lan {
 22     char name[25];
 23     int rd[4], sc36, sc72, dq;
 24     int rnds;
 25     bool star;
 26 
 27     Lan operator =(string &s) {
 28         FOR(i, 20) name[i] = s[i];
 29         name[20] = 0;
 30         star = false;
 31         if (strchr(name,'*'))
 32             star = true;
 33         sc36 = sc72 = dq = rnds = 0;
 34         memset(rd, 0, sizeof(rd));
 35         FOR(i, 4) {
 36             char t[5];
 37             FOR(j, 3) t[j] = s[20 + i * 3 + j];
 38             t[3] = '\0';
 39             if (!(sscanf(t, "%d", &rd[i]))) {
 40                 dq = -1;
 41                 rnds = i;
 42                 if (i < 2)
 43                     sc36 = -1;
 44                 break;
 45             }
 46             else {
 47                 sc72 += rd[i];
 48                 if (i < 2)
 49                     sc36 += rd[i];
 50             }
 51         }
 52         return *this;
 53     }
 54     Lan() {
 55         memset(name, 0, sizeof(name));
 56         FOR(i, 4) rd[i] = 0;
 57         sc36 = sc72 = dq =rnds= 0;
 58         star = false;
 59     }
 60 }lan[maxn];
 61 
 62 void print_result() {
 63     printf("Player Name          Place     RD1  RD2  RD3  RD4  TOTAL     Money Won\n-----------------------------------------------------------------------\n");
 64     int i = 0, cnt = 0;
 65     while (i < n) {
 66         if (lan[i].dq) {
 67             printf("%s           ", lan[i].name);
 68             FOR(k, lan[i].rnds)
 69                 printf("%-5d", lan[i].rd[k]);
 70             FOR(j, 4 - lan[i].rnds)
 71                 printf("     ");
 72             printf("DQ\n");
 73             i++;
 74             continue;
 75         }
 76         int j = i, m = 0, top = i + 1;
 77         double tot = 0.0;
 78         bool have_money = false;
 79         while (j < n&&lan[i].sc72 == lan[j].sc72) {
 80             if (!lan[j].star) {
 81                 m++;
 82                 if (cnt < n_cut) {
 83                     tot += money[cnt++];
 84                     have_money = true;
 85                 }
 86             }
 87             j++;
 88         }
 89         double totmoney = totle*tot / m;
 90         while (i < j) {
 91             printf("%s ", lan[i].name);
 92             char t[5];
 93             sprintf(t, "%d%c", top, (m>1 && have_money&& !lan[i].star) ? 'T' : ' ');
 94             printf("%-10s", t);
 95             FOR(k, 4)
 96                 printf("%-5d", lan[i].rd[k]);
 97             if (!lan[i].star&&have_money) {
 98                 printf("%-10d", lan[i].sc72);
 99                 printf("$%9.2f\n", totmoney / 100.0);
100             }
101             else
102                 printf("%d\n", lan[i].sc72);
103             i++;
104         }
105     }
106 }
107 
108 int main() {
109     int T;
110     cin >> T;
111     while (T--) {
112         cin >> totle;
113         FOR(i, 70) {
114             cin >> money[i];
115         }
116         cin >> n;
117         assert(n <= 144);
118         string s;
119         getline(cin, s);
120         FOR(i, n) {
121             getline(cin, s);
122             lan[i] = s;
123         }
124         sort(lan, lan + n, [](const Lan& t1, const Lan& t2) {
125             if (t1.sc36 < 0 && t2.sc36 < 0) return false;
126             if (t1.sc36 < 0) return false;
127             if (t2.sc36 < 0) return true;
128             return t1.sc36 < t2.sc36; });
129         //assert(lan[n_cut-1].sc36 >= 0);
130         int len = 0;
131         for (; len < n;len++)
132             if (lan[len].sc36<0)
133                 break;
134         if (len <= n_cut)
135             n = len;
136         else
137             for (int i = n_cut-1; i < n; i++)
138                 if (i == n - 1 || lan[i].sc36 != lan[i + 1].sc36||lan[i].sc36<0) {
139                     n = i + 1;
140                     break;
141                 }
142         sort(lan, lan + n, [](const Lan& t1, const Lan& t2) {
143             if (t1.dq&&t2.dq) {
144                 if (t1.rnds != t2.rnds)return t1.rnds>t2.rnds;
145                 if(t1.sc72!=t2.sc72) return t1.sc72 < t2.sc72;
146                 return strcmp(t1.name,t2.name) < 0;
147             }
148             if (t1.dq) return false;
149             if (t2.dq) return true;
150             if (t1.sc72 != t2.sc72) return t1.sc72 < t2.sc72;
151             return strcmp(t1.name,t2.name)< 0; });
152         print_result();
153         if(T) putchar('\n');
154     }
155     return 0;
156 }

劉老師的代碼:

 

  1 // UVa207 PGA Tour Prize Money
  2 // Rujia Liu
  3 #include<cstdio>
  4 #include<cstdlib>
  5 #include<cstring>
  6 #include<cmath>
  7 #include<algorithm>
  8 #include<cassert>
  9 using namespace std;
 10 
 11 #define REP(i,n) for(int i = 0; i < (n); i++)
 12 
 13 const int maxn = 144;
 14 const int n_cut = 70;
 15 
 16 struct Player {
 17   char name[25];
 18   int amateur;
 19   int sc[4];
 20   int sc36, sc72, dq;
 21   int rnds;
 22 } player[maxn];
 23 
 24 int n;
 25 double purse, p[n_cut];
 26 
 27 bool cmp1(const Player& p1, const Player& p2) {
 28   if(p1.sc36 < 0 && p2.sc36 < 0) return false; // equal
 29   if(p1.sc36 < 0) return false; // p2 smaller
 30   if(p2.sc36 < 0) return true; // p1 smaller
 31   return p1.sc36 < p2.sc36;
 32 }
 33 
 34 bool cmp2(const Player& p1, const Player& p2) {
 35   if(p1.dq && p2.dq) {
 36     if(p1.rnds != p2.rnds) return p2.rnds < p1.rnds;
 37     if(p1.sc72 != p2.sc72) return p1.sc72 < p2.sc72;
 38     return strcmp(p1.name, p2.name) < 0;
 39   }
 40   if(p1.dq) return false;
 41   if(p2.dq) return true;
 42   if(p1.sc72 != p2.sc72) return p1.sc72 < p2.sc72;
 43   return strcmp(p1.name, p2.name) < 0;
 44 }
 45 
 46 void print_result() {
 47   printf("Player Name          Place     RD1  RD2");
 48   printf("  RD3  RD4  TOTAL     Money Won\n");
 49   printf("---------------------------------------");
 50   printf("--------------------------------\n");
 51 
 52   int i = 0, pos = 0;
 53   while(i < n) {
 54     if(player[i].dq) {
 55       printf("%s           ",player[i].name);
 56       REP(j,player[i].rnds) printf("%-5d", player[i].sc[j]);
 57       REP(j,4-player[i].rnds) printf("     ");
 58       printf("DQ\n");
 59       i++;
 60       continue;
 61     }
 62 
 63     int j = i;
 64     int m = 0; // number of tied players
 65     bool have_money = false;
 66     double tot = 0.0; // total pooled money
 67     while(j < n && player[i].sc72 == player[j].sc72) {
 68       if(!player[j].amateur) {
 69         m++;          
 70         if(pos < n_cut) {
 71           have_money = true; // yeah! they still have money
 72           tot += p[pos++];
 73         }
 74       }
 75       j++;
 76     }
 77 
 78     // print player [i,j) together because they have the same rank
 79     int rank = i + 1; // rank of all these m players
 80     double amount = purse * tot / m; // if m=0, amount will be nan but we don't use it in that case :)
 81     while(i < j) {
 82       printf("%s ", player[i].name);
 83       char t[5];
 84       sprintf(t, "%d%c", rank, m > 1 && have_money && !player[i].amateur ? 'T' : ' ');
 85       printf("%-10s", t);
 86       REP(e,4) printf("%-5d", player[i].sc[e]);
 87 
 88       // with prize
 89       if(!player[i].amateur && have_money) {
 90         printf("%-10d", player[i].sc72);
 91         printf("$%9.2lf\n", amount / 100.0);
 92       } else
 93         printf("%d\n", player[i].sc72);
 94       i++;
 95     }
 96   }
 97 }
 98 
 99 int main() {
100   int T; 
101   char s[40];
102 
103   gets(s);
104   sscanf(s,"%d",&T);
105   while(T--) {
106     gets(s); // empty line
107 
108     // prize
109     gets(s);
110     sscanf(s,"%lf", &purse);
111     REP(i,n_cut) {
112       gets(s);
113       sscanf(s, "%lf", &p[i]);
114     }
115 
116     // players
117     gets(s);
118     sscanf(s, "%d", &n);
119     assert(n <= 144);
120     REP(k,n) {
121       // read a 32-character line
122       gets(s);
123 
124       // player name
125       strncpy(player[k].name, s, 20);      
126       player[k].name[20] = 0;
127       player[k].amateur = 0;
128       if(strchr(player[k].name, '*')) {
129         player[k].amateur = 1;
130       }
131 
132       // scores
133       player[k].sc36 = player[k].sc72 = player[k].dq=0;
134       memset(player[k].sc, -1, sizeof(player[k].sc));
135       REP(i,4) {
136         // raw score
137         char t[5];
138         REP(j,3) t[j] = s[20 + i*3 + j]; t[3] = '\0';
139 
140         // parse
141         if(!sscanf(t,"%d", &player[k].sc[i])) {
142           // DQ!
143           player[k].rnds = i;
144           player[k].dq = -1;
145           if(i < 2) player[k].sc36 = -1;
146           break; // skip other rounds (filled with -1, initially)
147         } else {          
148           player[k].sc72 += player[k].sc[i];
149           if(i < 2)
150             player[k].sc36 += player[k].sc[i];
151         }
152       }
153     }
154 
155     // round 1
156     sort(player, player+n, cmp1);
157     assert(player[n_cut-1].sc36 >= 0);
158     for(int i = n_cut-1; i < n; i++)
159       if(i == n-1 || player[i].sc36 != player[i+1].sc36) { n = i+1; break; }
160 
161     // round 2
162     sort(player, player+n, cmp2);
163     
164     // print result
165     print_result();
166  
167     if(T) printf("\n");
168   }
169   
170   return 0;
171 }

 

posted @ 2016-04-06 19:14  漫无目的的寻  阅读(607)  评论(0编辑  收藏  举报