HDU 1052 Tian Ji -- The Horse Racing (贪心)

###思路:
1,注意平局,平局不是一个值得追求的状态。
2,先把两人的马按升序排序,然后从双方最小的马比起,如果田忌的能赢,那就赢下一盘,此时赢下来是最优的选择,如果是输,那么就用这个最慢的马去怼king的最快的马,反正也是输,那就尽量为之后的队友创造一些优势。然后就是平局,如果平了,那么就先暂时搁置最慢的这边,转而去看最快的马,此时又分三种情况,1)咱胜,那就直接怼 2)咱输,那就用最慢的那匹马怼一个后来的优势(然后就可以接着从最慢的开始比起了) 3)怼平,这种情况下前后都陷入了平局的僵局,然而我们知道两场平局和一胜一败的得分一样,但一胜一败可以通过用最慢怼最快来制造优势,所以这时我们一般采取最慢怼最快的策略。有些眼尖的小伙伴可能会问,这样的话不就可以归在2)这种情况里吗?答案是:相等的情况需要特判。比如第二个样例:20 20 / 20 20 答案是0,但如果没有特判就可能出现-400的情况。(因为数列是有序的所以有些比较并没有真的比较而是直接改变了结果,所以才需要这个特判)

#include <iostream>
#include <cstdio>
#include <string.h>
#include <queue>
#include <algorithm>

using namespace std;

int t[1010];
int k[1010];
int t1,t2,k1,k2;

int main(){
    int n;
    while(scanf("%d",&n),n != 0){
        for(int i = 0;i < n;i++){
            scanf("%d",t+i);
        }
        for(int i = 0;i < n;i++){
            scanf("%d",k+i);
        }
        sort(t,t+n);
        sort(k,k+n);
        t2 = k2 = n-1;
        t1 = k1 = 0;
        int cnt = n;
        int ans = 0;
        while(cnt != 0){
            if(t[t1] > k[k1]){
                ans++;
                t1++,k1++;
            }
            else if(t[t1] < k[k1]){
                t1++;
                k2--;
                ans--;
            }
            else if(t[t1] == k[k1]){
                if(t[t2] > k[k2]){
                    ans++;
                    t2--,k2--;
                }
                else if(t[t2] < k[k2]){
                    t1++;
                    k2--;
                    ans--;
                }
                else{
                    if(t[t1] < k[k2]){
                        ans--,t1++,k2--;
                    }
                    else{
                        t1++,k2--;
                    }
                }
            }
            cnt--;
        }
        printf("%d\n",200*ans);
    }
}

多年之后,重新写了一遍

#include <bits/stdc++.h>
using namespace std;

int a[1020];
int b[1020];
int main() {
    int n;
    while (scanf("%d", &n) && n != 0) {
        int ans = 0;
        for (int i = 1; i <= n; i++) {
            scanf("%d", a + i);
        }
        for (int i = 1; i <= n; i++) {
            scanf("%d", b + i);
        }
        sort(a + 1, a + 1 + n);
        sort(b + 1, b + 1 + n);
        int al = 1, ar = n, bl = 1, br = n;
        while (al <= ar && bl <= br) {
            if (a[al] == b[bl]) {
                //如果这时候可以赢,那就快打快。cost最小。
                if (a[ar] > b[br]) {
                    ar--;
                    br--;
                    ans++;
                } else {  //两边都相等的情况。
                    // a最快的 <= b最快的,那么就用a最慢的去换b最快的,反正值。
                    if (a[al] < b[br])
                        ans--;  //唯一需要判断的就是换的时候,究竟有没有花费
                    al++;
                    br--;
                }
            }
            //如果a最慢的快于b最慢的,直接赢,因为这样损失最小
            else if (a[al] > b[bl]) {
                ans++;
                al++;
                bl++;
            }
            // a最慢的 慢于
            // b最慢的,反正都是输,用a最慢的去换b最快的。而且因为a_0 < b_0
            // b有序,所以a_0 < b_r
            else {
                ans--;
                al++;
                br--;
            }
        }
        printf("%d\n", ans * 200);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值