UPC(混合8)问题 D: 田忌赛马

标签:思维
时间限制: 1 Sec 内存限制: 128 MB

题目描述
他是一匹棕色的马。他在奔跑,和一群马一起奔跑。
这是那片古老大地上流传着的一个故事,关于马的故事。马之故事,以鞍为墨。
现在,田忌又一次与人赛马。不过不同的是,赛制发生了变化。田忌与对手决定一场定胜负。双方都不能选择自己参赛的马,他们用于一决高下的马将在自己的所有马中随机产生。每一匹马都有一个能力值。能力值较高的马获胜。当两匹马能力值相同时这场比赛被视为平局。
运筹帷幄的田忌不想在未知中等待结果的到来,所以他想知道自己获胜的概率是多少。
输入
第1行一个正整数T,表示数据组数。
对于每组数据,第1行两个正整数N,M,分别表示田忌和对手拥有的马的数量。
第2行N个正整数,第i个正整数Ai表示田忌第i匹马的能力值。
第3行M个正整数,第i个正整数Bi表示对手第i匹马的能力值。
输出
共T行‬对每组数据,一行一个分数,“x/y”(不含引号)
,表示田忌获胜的概率(最简分数)
。
样例输入
1
3 5
4 3 7
1 9 4 6 10
样例输出
1/3
提示
样例解释
为方便解释,我们称一组随机选马为二元组(x,y)
,x,y分别代表田忌和对手的马的能力值。
当二元组为(4,1)、(3,1)、(7,1)、(7,4)、(7,6)时,田忌获胜,共5种。
随机选马共有3×5=15种方法。
所以田忌获胜的概率为5/15,化为最简分数为1/3。

对于100%的数据,1≤N,M≤40000;1≤Ai,Bi<10^9,1≤T≤5

我这人喜欢“暴力”求解,但往往是费了精力和时间,却得不到ac,以后要多动动脑子,多向dalao学习思考方式。

思路比较简单:
另外开一个数组c记录田忌的第i 匹马的获胜次数,将a[n],b[m]排序之后,假设田的第x匹马可以战胜y匹马,那么第x+1匹马一定可以战胜这y匹马,所以我们的二重循环的第二重,就不必每次都从0开始,这样便减小了复杂度,顺利ac。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <vector>
#include <queue>
#include <ctime>
#define ll long long
#define inf 0x3f3f3f3f
//#define local
using namespace std;
const int N = 40010;
int t,n,m;
int a[N],b[N],c[N];
int gcd(int a,int b)
{
    if(!b)
        return a;
    else
        return gcd(b,a%b);
}

int main()
{
#ifdef local
    freopen("input.txt","r",stdin);
#endif // local
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        int num=0;
        memset(c,0,sizeof(c));
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        for(int i=1; i<=n; i++)
            scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        for(int j=1; j<=m; j++)
            scanf("%d",&b[j]);
        sort(b+1,b+m+1);
        int j=1;
        for(int i=1; i<=n; i++)
        {
            c[i]+=c[i-1];
            while(j<=m)
            {
                if(a[i]>b[j])
                    c[i]++,j++;
                else
                    break;
            }
           num+=c[i];
        }
        int t=gcd(num,n*m);
        printf("%d/%d\n",num/t,m*n/t);

    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值