紫書_例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 }
漫無目的的尋,尋一個夢,夢紫幽蘭