此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。
题目链接:http://poj.org/problem?id=2287
题目大意:
田忌赛马的故事就不用多说了吧....
输入包含多组数据(<=50),以0作为结束标志。
每组数据的第一行给出一个数n(n<=1000),表示齐王和田忌各有多少匹马。
第二行有n个数,表示田忌的马的速度值。
第三行有n个数,表示齐王的马的速度值。
在比赛中,速度值较大的马一定获胜。约定每局比赛中败者付给胜者200银币,平局则双方均无损失。问田忌最多能赢得多少银币。
Sample Input
3 92 83 71 95 87 74 2 20 20 20 20 2 20 19 22 18 0
Sample Output
200 0 0
分析:
洛谷上也有类似的题(P1650),然而洛谷的题目描述里提到了二分图匹配,好像把人给吓到了2333
贪心。先把马的速度值从小到大排个序。
每一局比赛,先判断当前田忌最快的马能否战胜齐王最快的马,如果能,则赢得200银币,否则进行第二步判断。
第二步:判断当前田忌最慢的马能否战胜齐王最慢的马,如果能,则赢得200银币,否则用最慢的马去对战齐王最快的马,失去200银币。
还要注意平局的情况,如果田忌和齐王最慢的马速度相等,且最慢的马和最快的马速度也相等,才有平局的必要(而且只能平局)。
否则用最慢的马去对战齐王最快的马,结果不会更坏。
其实在判断的时候是不需要把a,b变成0的,反正你之后也不可能再遇到....窝只是强迫症一下qwq
AC代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 6 const int MAXN = 2005; 7 8 inline void read(int &x) 9 { 10 char ch = getchar(),c = ch;x = 0; 11 while(ch < ‘0‘ || ch > ‘9‘) c = ch,ch = getchar(); 12 while(ch <= ‘9‘ && ch >= ‘0‘) x = (x<<1)+(x<<3)+ch-‘0‘,ch = getchar(); 13 if(c == ‘-‘) x = -x; 14 } 15 16 int a[MAXN],b[MAXN]; 17 // 田忌马 齐王马 18 int n,m,ans = 0; 19 20 inline void init() 21 { 22 m = n,ans = 0; 23 memset(a,0,sizeof(a)); 24 memset(b,0,sizeof(b)); 25 } 26 27 int main() 28 { 29 30 read(n); 31 while(n) 32 { 33 init(); 34 for(int i = 1;i <= n;++ i) 35 read(a[i]); 36 for(int i = 1;i <= n;++ i) 37 read(b[i]); 38 std::sort(a+1,a+1+n); 39 std::sort(b+1,b+1+n); 40 if(a[n] < b[1]) 41 ans = -200*n; 42 else if(a[1] > b[n]) 43 ans = 200*n; 44 //两种特殊情况:全输/全赢 45 else 46 { 47 int i = 1,j = 1; 48 while(i <= n && j <= m) 49 { 50 if(a[n] > b[m]) 51 { 52 a[n--] = 0,b[m--] = 0,ans += 200; 53 } 54 else if(a[i] > b[j]) 55 { 56 a[i++]= 0,b[j++] = 0,ans += 200; 57 } 58 else if(a[i] == b[j] && a[i] == b[m]) 59 { 60 a[i++] = 0,b[j++] = 0; 61 } 62 else 63 a[i++] = 0,b[m--] = 0,ans -= 200; 64 } 65 } 66 printf("%d\n",ans); 67 read(n); 68 } 69 return 0; 70 }
时间: 2024-11-04 01:10:08