题目链接
经典的贪心问题。主要是要分析清楚,要贪到那个点不然必然WA.还有做题的技巧很重要。我一开始用结构体数组再做,过于复杂了,不知道错在哪。找了N多数据终于发现错误的数据,但由于数据太大,也无力再去查错了。所以这题,再次告诉我,做题简化思维的重要性!
下面分析下题目:
田忌最弱的和王最弱的比较
如果,王最弱的比田最弱的还弱,
那么你肯定要用最低的代价去PK掉赚的这200吧?所以拿最低的和王最低的PK。
如果王最弱的比田忌最弱的还要强,
那么也就是说你那只最弱的是注定要输掉200的,那么肯定拿去和他最强的比比,反正是输,拉下水一只大的总是最值的。
最后是如果最弱的相等呢,
这时候,就去看看最强的,
如果田最强的比王最强的还强,那肯定也是干掉了。不然还白白放走这200?
如果田最强的比王最强的还弱,那没办法了,肯定没有干的过它的了,那不如就拿最弱的这只去和它干吧,反正是输,用最小的代价。
如果田最强的和王最强的一样强,那顶多就打个平手吧。这时候不妨也拿最弱的和它干,这样能保证田拿最小的换掉王最大的,而且田这个小的是肯定可以再换掉王最小的那个,但也可能可以换掉王任意一只大于最小的那只。
下面是之前写过的代码,基本数据都对,大数据死命WA,祭奠我无辜死去的脑细胞:
#include <iostream> #include <limits.h> using namespace std; typedef struct hou{ int s; bool flag; }hou; int getMax(hou s[], int n){ int max, j; max = INT_MIN; j = 0; for (int i = 0; i < n; i++){ if (s[i].flag) { if (max <= s[i].s){ max = s[i].s; j = i; } } } return j; } int getMin(hou s[], int n){ int min, j; min = INT_MAX; j = 0; for (int i = 0; i < n; i++){ if (s[i].flag) { if (min > s[i].s){ min = s[i].s; j = i; } } } return j; } int main() { freopen("output.txt", "w", stdout); hou s1[1050], s2[1050]; int min1, min2, max1, max2; int n, sum; while (cin >> n&&n){ sum = 0; for (int i = 0; i < n; i++){ cin >> s1[i].s; s1[i].flag = true; } for (int i = 0; i < n; i++){ cin >> s2[i].s; s2[i].flag = true; } for (int i = 0; i < n; i++){ min1 = getMin(s1, n); min2 = getMin(s2, n); max1 = getMax(s1, n); max2 = getMax(s2, n); if (s1[min1].s > s2[min2].s) //田最弱比大王最弱强直接PK { s1[min1].flag = s2[min2].flag = false; sum += 200; } else if (s1[min1].s < s1[min2].s)//田最弱比大王最弱还弱,就去和大王最强的PK { s1[min1].flag = s2[max2].flag = false; sum -= 200; } else //最弱相等的情况 { if (s1[max1].s>s2[max2].s){ //最强的比大王强,PK掉 s1[max1].flag = s2[max2].flag = false; sum += 200; } else if (s1[max1].s <= s2[max2].s){//最强的比大王的弱(或是相等),用最弱的和大王最强的PK s1[min1].flag = s2[max2].flag = false; if (s1[min1].s < s2[max2].s) sum -= 200; } } } cout << sum << endl; } return 0; }
下面是AC代码,参考别人写的,加了很多自己理解的注释:
#include <iostream> #include <algorithm> using namespace std; bool cmp(const int &a, const int &b) { return a<b; } int t[1005], k[1005]; int main() { int i, tmax, kmax, tmin, kmin, n, sum; while (scanf("%d", &n) != EOF) { if (n == 0) break; for (i = 0; i<n; i++) scanf("%d", &t[i]); for (i = 0; i<n; i++) scanf("%d", &k[i]); sort(t, t + n, cmp); //升序排列 sort(k, k + n, cmp); sum = 0; for (tmin = 0, kmin = 0, tmax = n - 1, kmax = n - 1; tmin <= tmax && kmin <= kmax;) { if (t[tmin]>k[kmin])//田最弱比王最弱强直接PK掉 { sum = sum + 200; tmin++; kmin++; continue; } if (t[tmin]<k[kmin])//田最弱比王最弱弱,用田最弱去PK王最强 { sum = sum - 200; tmin++; kmax--; continue; } if (t[tmin] == k[kmin])//相等 { if (t[tmax]>k[kmax])//田最强比王最强强 直接PK掉 { sum = sum + 200; tmax--; kmax--; continue; } if (t[tmax]<k[kmax])//田最强比王最强弱 { sum = sum - 200; tmin++; kmax--; continue; } if (t[tmax] == k[kmax]) { if (t[tmin]<k[kmax]) sum = sum - 200; tmin++; kmax--; continue; } } } cout << sum << endl; } return 0; }
总结:
我摄影的时候,总是喜欢挑一些不寻常的角度去拍下他,因为我觉得,很多东西,如果我们只是从正常的角度观看它,往往不能获得真正的感受。所以,我会不断寻找新的角度。而做题如是,如果只是普通的思维,永远也只能局限在不断DEBUG的基础上。所以我要努力,提升思维!
我可以走的很慢,但是,一定要前进。
至少,要比昨天的自己强!