My Brute

                                 My Brute


题目链接:Click Here~

题目分析:

   有两个人进行游戏对决,就是跟拳王游戏一样的。游戏规则是每个人都有N个游戏人物,以及每个人物有有其自己的伤害值和血量。而每个游戏者获胜又都会相应的获得一些分数。现在已经给出了两个人的各自N个游戏人物的出场顺序,要求你用最少的交换次数来获得最大的分数值。


思路分析:

    跟HDU Assignment一样的。都是对原来的值进行扩展以保证优先选原来的点。别的就不说了,因为思路跟那题一样的。但是用那题的建图方法一直TEL。。。。无解。


#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAXN 100
#define MAX 1010
#define INF 100000000

int W[MAXN][MAXN],N,slack;
int V[MAXN],H[MAXN],P[MAXN],A[MAXN],B[MAXN];
int Lx[MAXN],Ly[MAXN],Link[MAXN];
bool S[MAXN],T[MAXN];
int Win(int i,int j)
{
    if((H[i]-1) / B[j] >= (P[j]-1)/A[i])
        return V[i];
    else
        return -V[i];

}
inline int Read()
{
    char ch = getchar();
    while(!isdigit(ch)) ch = getchar();
    int sum = 0;
    while(isdigit(ch)){
        sum *= 10;
        sum += ch - '0';
        ch = getchar();
    }
    return sum;
}
void Init()
{
    int i,j;
    memset(W,0,sizeof(W));
    for(i = 1;i <= N;++i)
        V[i] = Read();
    for(i = 1;i <= N;++i)
        H[i]= Read();
    for(i = 1;i <= N;++i)
        P[i]= Read();
    for(i = 1;i <= N;++i)
        A[i]= Read();
    for(i = 1;i <= N;++i)
        B[i]= Read();
    for(i = 1;i <= N;++i){
        for(j = 1;j <= N;++j){
            W[i][j] = 10 * (Win(i,j) + MAX);
            if(i == j)
                W[i][j] += 1;
        }
    }
}
int Match(int i)
{
    int j,tmp;
    S[i] = 1;
    for(j = 1;j <= N;++j)if(!T[j]){
        tmp = Lx[i] + Ly[j] - W[i][j];
        if(tmp==0){
            T[j] = 1;
            if(Link[j]==-1||Match(Link[j])){
                Link[j] = i;
                return 1;
            }
        }
        else if(tmp < slack)
            slack = tmp;
    }
    return 0;
}
int EK()
{
    int i,j;
    for(i = 1;i <= N;++i){
        Link[i] = -1;
        Lx[i] = Ly[i] = 0;
        for(j = 1;j <= N;++j)
           if(Lx[i] < W[i][j])
              Lx[i] = W[i][j];
    }

    for(i = 1;i <= N;++i){
        for(;;){
            memset(S,0,sizeof(S));
            memset(T,0,sizeof(T));
            slack = INF;
            if(Match(i))
                break;
//            if(slack == INF)
//                return 0;

            //update
            for(j = 1;j <= N;++j){
              if(S[j])
                Lx[j] -= slack;
              if(T[j])
                Ly[j] += slack;
             }
        }
    }
    return 1;
}
//int Get()
//{
//    int i,sum = 0;
//    for(i = 1;i <= N;++i){
//        if(Link[i]!=-1)
//            sum += W[Link[i]][i];
//    }
//    return sum;
//}
void printresult()
{
    int i, res = 0, num = 0;
    for(i = 1; i <= N; i ++)
    {
        if(W[Link[i]][i] % 10 != 0)
            num ++;
        res += W[Link[i]][i] / 10 - MAX;
    }
    if(res > 0)
        printf("%d %.3f%%\n", res, 100.0 * num / N);
    else
        printf("Oh, I lose my dear seaco!\n");
}
int main()
{
//    freopen("Input.txt","r",stdin);

    while(scanf("%d",&N),N)
    {
        Init();
        EK();
        printresult();
//        int sum = Get();
//        if(sum >= 0){
//
//            double rati = sum%MAXN*1.0/N;
//            printf("%d %.3lf%%\n",sum/MAXN,rati*100.0);
//        }
//        else
//            puts("Oh, I lose my dear seaco!");
    }
    return 0;
}







  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值