HDOJ 1052 Tian Ji -- The Horse Racing

题目链接


经典的贪心问题。主要是要分析清楚,要贪到那个点不然必然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的基础上。所以我要努力,提升思维!

我可以走的很慢,但是,一定要前进。

至少,要比昨天的自己强!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值