题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1052

错误代码:

#include<stdio.h>//田忌赛马,错误版
#include<string.h>
#include<stdlib.h>
/*思路:用田忌最快的马与齐王最快的马比较,1.若能赢就赢;2.若赢不了,就用最差的马拖齐王最好的马入水;3.若打平:要判断是否在最好一匹马,
若是,则打平,若不是,则用最差的一匹马拖它下水,虽然输了这次,但下次有机会赢回。看似无差别,但这样做却保留了最多的好马。
然而这种思靠虽然完备,但方向一开始已经错了。为什么田忌自己赛会输,因为他用最好的马与最好的马去比,硬碰硬。然而孙膑的想法是
避其锋芒,攻其弱点,也就是说,要赢比赛,就要尽量在齐王的弱马上赢,因为这样成本低,收益更大。而不是在齐王的强马上赢得比赛。
所以比赛从齐王最弱的马开始kill。
int cmp(const void*a, const void*b)
{
return *(int*)b - *(int*)a;
} int main()
{
int n,i,j,m,t[1010],k[1010];
while(scanf("%d",&n) && n)
{
for(i = 0; i<n; i++) scanf("%d",&t[i]);
for(i = 0; i<n; i++) scanf("%d",&k[i]);
qsort(t,n,sizeof(t[0]),cmp);
qsort(k,n,sizeof(k[0]),cmp); m = 0;
int th = 0,tt = n-1,kh = 0;
while(kh<n)
{
if(t[th]>k[kh]) {th++;kh++;m++;}
else if(t[th]<k[kh]) {tt--;kh++;m--;}
else
{
if(kh==n-1) {th++; kh++;}
else {tt--; kh++; m--;}
}
} printf("%d\n", m*200);
}
return 0;
}

正确代码:

#include<stdio.h>//正确方案,从弱马开始
#include<string.h>
#include<stdlib.h> int cmp(const void*a, const void*b)
{
return *(int*)b - *(int*)a;
} int main()
{
int n,i,j,m,t[1010],k[1010];
while(scanf("%d",&n) && n)
{
for(i = 0; i<n; i++) scanf("%d",&t[i]);
for(i = 0; i<n; i++) scanf("%d",&k[i]);
qsort(t,n,sizeof(t[0]),cmp);
qsort(k,n,sizeof(k[0]),cmp); m = 0;
int th = 0,tt = n-1,kh = 0,kt = n-1;
while(th<=tt)
{
if(t[tt]>k[kt])//田弱能赢齐弱,则赢
{tt--; kt--; m++;}
else if(t[tt]<k[kt])//田弱输齐弱,反正都要死,这匹弱马就要死得最有价值,用它去拖齐强下水
{tt--;kh++; m--;}
else
{
/*田弱平齐弱,总体来说,这匹田弱拿去拖齐强下水,那么田忌获胜的机会更大些,但有例外,
就是万一这匹弱马死得不值呢:田强本来就可以赢齐强,还何必用田弱拖它下水,况且齐弱本可以平局,
这样搞就反而输掉了一局*/
if(t[th]>k[kh])//所以这里要判断田强是否赢齐强,看看田弱是否死得有价值
{th++; kh++; m++;}//死得没价值,这局就让田强赢齐强
else if(t[th]<k[kh])//死得有价值,上吧,田忌会记住你的
{tt--; kh++; m--;} else //田强平齐强,为了保存实力,也让齐弱上(但田弱不一定输)。
{
if(t[tt]<k[kh]) m--;//田弱可能平田强,当田强平齐强时,要判断田弱是否真的弱于田强,可能打平
tt--; kh++;
}
}
}
printf("%d\n", m*200);
}
return 0;
}
05-11 13:18