田忌赛马&拼点游戏

田忌赛马

还是English,要不是看题目,我都被原题整懵了,直接上Chinese吧
Descriptions:
田忌和齐王赛马,他们各有n匹马,依次派出一匹马比赛,赢了加200,输了减200,平局不加钱,问如何安排马的出场顺序,使得田忌赢的钱最多
Input
输入最多包含 50 组测试数据。对于每组测试数据,第一行包括一个正整数 n (n ≤ 1000),表示每一方的马的数目。第二行中的 n 个整数,表示田忌的马的速度。第三行中的 n 个整数,表示齐王的马的速度。在最后一组测试数据之后,是只包含单个 0 的一行。
Output
对于每组测试数据,输出包含单个数的一行,表示田忌将从齐王那里赢得银两的最大值。
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

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#define mod 1000000007
#define eps 1e-6
#define ll long long
#define INF 0x3f3f3f3f
#define ME0(x) memset(x,0,sizeof(x))
using namespace std;
int n;
int a[1005];
int b[1005];
int main()
{
    while(cin>>n,n)
    {
        ME0(a);
        ME0(b);
        int sum=0;
        for(int i=0; i<n; i++)
            cin>>a[i];//田忌的马
        for(int i=0; i<n; i++)
            cin>> b[i];//齐王的马
        sort(a,a+n);//排序
        sort(b,b+n);
        int l1=0;
        int l2=0;
        int r1=n-1;
        int r2=n-1;
        while(l1<=r1)
        {
            //田忌最快的马比齐王最快的马快,则两者比
            if(a[r1]>b[r2])
            {
                sum+=200;
                --r1;
                --r2;
            }
            //田忌最快的马比齐王最快的马慢,则用田忌最慢的马和齐王最快的马比
            if(a[r1]<b[r2])
            {
                sum-=200;
                ++l1;
                --r2;
            }
            //速度相等
            if(a[r1]==b[r2])
            {
                //田忌最慢的马比齐王最慢的马快,则这两匹马比
                if(a[l1]>b[l2])
                {
                    sum+=200;
                    ++l1;
                    ++l2;
                }//否则,用田忌最慢的马和齐王最快的马比
                else
                {
                    if(a[l1]<b[r2])//田忌最慢的马比齐王最快的马快
                        sum-=200;//加200
                    ++l1;//否则平局
                    --r2;
                }
            }
        }
        cout<<sum<<endl;
    }
}

原题链接

拼点游戏

Descriptions:
C和S两位同学一起玩拼点游戏。有一堆白色卡牌和一堆蓝色卡牌,每张卡牌上写了一个整数点数。C随机抽取n张白色卡牌,S随机抽取n张蓝色卡牌,他们进行n回合拼点,每次两人各出一张卡牌,点数大者获得三颗巧克力,小者获得一颗巧克力,如果点数相同,每人各得二颗巧克力,使用过的卡牌不得重复使用。已知C和S取到的卡牌点数,请编程计算S最多和最少能得到多少颗巧克力。
Input
输入包含多组测试数据。
每组测试数据的第一行是一个整数n(1<=n<=1000),接下来一行是n个整数,表示C抽到的白色卡牌的点数,下一行也是n个整数,表示S抽到的蓝色卡牌的点数。
输入的最后以一个0表示结束。
Output
对每组数据,输出一行,内容是两个整数用空格格开,分别表示S最多和最少可获得的巧克力数。

Sample Input
3
92 83 71
95 87 74
2
20 20
20 20
2
20 19
22 18
0
Sample Output
9 5
4 4
4 4

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#define mod 1000000007
#define eps 1e-6
#define ll long long
#define INF 0x3f3f3f3f
#define ME0(x) memset(x,0,sizeof(x))
using namespace std;
int n;
//这就是田忌赛马好吗0.0  不会的看我田忌赛马博客  讲的比较细
//  https://www.cnblogs.com/sky-stars/p/11073032.html
int solve(int c[1005],int s[1005])
{
    int ans=0;
    int cl=1,cr=n,sl=1,sr=n;
    while(sl<=sr)
    {
//        cout<<sr<<"*       *"<<sl<<endl;
//        cout<<s[sr]<<"    "<<c[cr]<<endl;
        if(s[sr]>c[cr])
        {
            --sr;
            --cr;
            ans+=3;
        }
        else if(s[sr]<c[cr])
        {
            ++sl;
            --cr;
            ans+=1;
        }
        else
        {
            if(s[sl]>c[cl])
            {
                ++sl;
                ++cl;
                ans+=3;
            }
            else
            {
                if(s[sl]<c[cr])
                {
                    ++sl;
                    --cr;
                    ans+=1;
                }
                else
                {
                    ++sl;
                    --cr;
                    ans+=2;
                }
            }
        }
    }
    return ans;
}
int main()
{
    while(cin>>n,n)
    {
        int a[1005];
        int b[1005];
        ME0(a);
        ME0(b);
        for(int i=1; i<=n; ++i)
            cin>>a[i];//C的卡牌
        for(int i=1; i<=n; ++i)
            cin>>b[i];//S的卡牌
        sort(a+1,a+1+n);
        sort(b+1,b+1+n);
        cout<<solve(a,b)<<" ";//求C的最大得分
        //每一局总分一定是4,//求出S的最大得分,就求出了C的最小得分
        cout<<4*n-solve(b,a)<<endl;
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值