周赛-Heros and Swords 分类: 比赛 2015-08-02 08:30 11人阅读 评论(0) 收藏

时间:2021-10-24 18:51:08

Heros and Swords

Time Limit: 6000/3000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)

Problem Description

There are n swords of different weights Wi and
n heros of power Pi.

Your task is to find out how many ways the heros can carry the swords so that each hero carries exactly one sword.

周赛-Heros and Swords                                                       分类:            比赛             2015-08-02 08:30    11人阅读    评论(0)    收藏

Here are some rules:

(1) Every sword is carried by one hero and a hero cannot carry a sword whose weight is larger than his power.

(2) Two ways will be considered different if at least one hero carries a different sword.

Input

The first line of the input gives the number of test cases T(1 ≤ T ≤ 50).

Each case starts with a line containing an integer n (1 ≤ n ≤ 105) denoting
the number of heros and swords.

The next line contains n space separated distinct integers denoting the weight of swords.

The next line contains n space separated distinct integers denoting the power for the heros.

The weights and the powers lie in the range [1, 109].

Output

For each case, output one line containing "Case #x: " followed by the number of ways those heros can carry the swords.

This number can be very big. So print the result modulo 1000 000 007.

Sample Input

3
5
1 2 3 4 5
1 2 3 4 5
2
1 3
2 2
3
2 3 4
6 3 5

Sample Output

Case #1: 1
Case #2: 0
Case #3: 4
一道贪心的题,在贪心中处理组合数用的2*n的时间复杂度,精妙
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <list>
#include <algorithm>
#define LL long long
#define RR freopen("output.txt","r",stdoin)
#define WW freopen("input.txt","w",stdout) using namespace std; const int MAX = 100100; const int MOD = 1000000007; int n; int w[MAX],p[MAX]; int num[MAX]; int main()
{
int T;
int W=1;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&w[i]);
}
for(int i=0;i<n;i++)
{
scanf("%d",&p[i]);
}
sort(w,w+n);
sort(p,p+n);
        for(int i=0,j=0;i<n;i++)//贪心
{
while(j<n&&w[j]<=p[i])
{
j++;
}//此时这个人可以拿加j-1个兵器,而前面的i-1个人已经拿了i-1个,所以他还可以拿(j-1-(i-1))=j-i个;
num[i]=j-i;
}
LL ans=1;
for(int i=0;i<n;i++)
{
ans=(ans*num[i])%MOD;
if(!ans)
{
break;
}
}
printf("Case #%d: %lld\n",W++,ans);
}
return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。