Taekwondo

Taekwondo

There are an individual match and group match in Taekwondo. An individual match is between two players and a group match is repetition of matches between two different individual players of each group.
You plan to make a group match which is comprised of several individual matches by selecting each player from each group. Every player of the group can play one match only. Therefore, the number of matches is the same as the smaller number of the players of the two groups. Like other sports, Taekwondo has a rule to make a weight difference minimal between two players of a match to be fair. 
In a given two players’ groups, create a program to make a group match with the total sum of absolute weight differences to a minimum between each two players who participate in each individual game. 

Time limit: 1 second (java: 2 seconds)

[Input]
Several test cases can be included in the inputs. T, the number of cases is given in the first row of the inputs. After that, the test cases as many as T (T ≤ 30) are given in a row. 
The number of players in the first group, N and the number of players in the second group, M are given as being separated with a blank. (1 ≤ N, M ≤ 500) 
The players’ weights of the second group are given respectively from the next row to M number rows. Each player weight is a real number over 40.0 below 130.0, and a weight to be inputted has an accuracy of one place of decimal. 

[Output]
For each test case, you should print "Case #T" in the first line where T means the case number.

For each test case, you should outputthe total sum of absolute values of two players’ weights participating in an individual game included in a group match to one decimal place on the first row of each test case. 

[I/O Example]

Input
2
2 4
55.0
50.0
60.0
48.0
53.5
43.0
1 5
106.8
55.7
46.4
78.8
103.1
56.0

Output
Case #1

3.5

Case #2

3.7

题意大概有一下四点:

1.         两队人做跆拳道比赛;

2.         比赛场次等于人少的一组;

3.         比赛中两个选手会存在重量差;

4.         求一种能够安排的最小重量差;

 

解题思路为动态规划(贪婪算法并不一定是最优解,有反例),核心伪代码如下:

f(i,j) = min {f(i,j-1), f(i-1, j-1)+d(I,j)}  i<j

    = f(i-1,j-1)+d(i,j)             i=j

    = 0                       i=0 or j=0 or i>j

 

 

C代码如下:

/*

You should use the statndard input/output

 

in order to receive a score properly.

 

Do not use file input and output

 

Please be very careful.

*/

#include <stdio.h>

 

#define MAX_N 501

 

float Array_one[MAX_N];

float Array_two[MAX_N];

float temp[MAX_N];

 

float Answer[MAX_N] ;

 

 

float Dif_Abs(float a , float b)//ab进行做差并返回绝对值{

if(a >= b)

return (a-b);

else

return (b-a);

}

 

/********************************************************************

归并排序算法,对拆分之后的数组进行排序合并

a[]:需要排序的数组;

temp[]:临时存放排序过程中的a[]的临时数组;

start:开始排序的数组的位置;

Middle:从startend中间的位置;

end:结束排序的数组的位置;

********************************************************************/

void MeageArray(float a[],float temp[] ,int start ,int middle ,int end)

{

    int s,m,e,k,i;

    s = start ;

    m = middle + 1 ;

    e = end ;

    k = start ;

   

    while((s<=middle)&&(m<=end))

    {

        if(a[s] <= a[m])

        {

            temp[k++] = a[s++] ;

        }

   

        else//if(a[s] > a[m])

        {

            temp[k++] = a[m++] ;

        }

    }

   

    while(s <= middle)

    {

        temp[k++] = a[s++];

    }

   

    while(m <= end)

    {

        temp[k++] = a[m++];

    }

   

    for(i = start ; i <= end ; i++)

    {

        a[i] = temp[i];

    }  

}

 

/********************************************************************

归并排序算法,对数组进行拆分,分别将左边和右边拆分成最小单元,然后再合并;

a[]:需要排序的数组;

temp[]:临时存放排序过程中的a[]的临时数组;

start:开始排序的数组的位置;

end:结束排序的数组的位置;

********************************************************************/

void MergeSort(float a[],float temp[],int start,int end)

{

    int middle ;

   

    if(start < end)

    {

        middle = (start + end)/2 ;

        MergeSort(a , temp , start , middle);

        MergeSort(a , temp , middle+1 , end);

        MeageArray(a,temp , start , middle , end);

    }

}

 

int main(void)

{

   

   

    int T, test_case;

   

   

    /*

   

   

    The freopen function below opens input.txt file in read only mode, and afterward,

   

   

    the program will read from input.txt file instead of standard(keyboard) input.

   

   

    To test your program, you may save input data in input.txt file,

   

   

    and use freopen function to read from the file when using scanf function.

   

   

    You may remove the comment symbols(//) in the below statement and use it.

   

   

    But before submission, you must remove the freopen function or rewrite comment symbols(//).

   

   

    */

   

   

    freopen("sample_input.txt""r", stdin);

 

    /*

   

   

    If you remove the statement below, your program's output may not be rocorded

   

   

    when your program is terminated after the time limit.

   

   

    For safety, please use setbuf(stdout, NULL); statement.

   

   

    */

   

   

    setbuf(stdout, NULL);  

   

   

    scanf("%d", &T);

   

    for(test_case = 0; test_case < T; test_case++) 

    {

        int N,M;

        int i,j;

        int n1,m1;

        scanf("%d",&N);

        scanf("%d",&M);

       

        for(i=0;i<N;i++)

        {

            scanf("%f",&Array_one[i]);

        }

       

        for(j=0;j<M;j++)

        {

            scanf("%f",&Array_two[j]);

        }

 

        for(j=0;j<MAX_N;j++)//初始化每一个caseAnswer数组

        {

            Answer[j] = 0;

        }

       

        MergeSort(Array_one,temp,0,N-1);//对第一队人按照体重由小到大进行排序

        MergeSort(Array_two,temp,0,M-1);//对第二队人按照体重由小到大进行排序

        if(N<M) //判断两队人数的多少,用人数少的一队去遍历人数多的一队

        {

            n1 = N ;

            m1 = M ;

        }

        else

        {

            n1 = M ;

            m1 = N ;

        }

       

        for(i=0;i<n1;i++) //核心代码部分

        {

            for(j=0;j<m1-n1+1;j++)

            {

                Answer[j] +=Dif_Abs(Array_one[i] , Array_two[i+j]);

 

                if((j > 0) && (Answer[j] > Answer[j-1]))

                {

                    Answer[j] = Answer[j-1];

                }

            }

        }  

       

        /

       

       

        /*

       

       

        Implement your algorithm here.

       

       

        The answer to the case will be stored in variable Answer.

       

       

        */

       

       

        /

       

       

        //Answer = 0;

 

        // Print the answer to standard output(screen).

       

       

    printf("Case #%d\n", test_case+1);

       

    printf("%.1f\n", Answer[m1-n1]);

   

   

    }

    return 0;//Your program should return 0 on normal termination.

   

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值