zoukankan      html  css  js  c++  java
  • 北大poj1018题解题报告

    //我是莱鸟,多多交流

    //380k

    //94ms

    题目的意思是:每种装备可由多个生产商提供,从每一种装备中选择一个厂家的设备,使得所选的总的各种装备中的最小带宽B与他们的价格之和P的比值B/P达到最大。

    解题思路:

    准备工作:在输入时,统计所有装备中的最小值min,和每种装备中的最大值max,然后从最大值中选出最小的一个Max。

    然后:从最小值min到Max之间枚举所有的可能的结果,并输出最大的一个值

    1、对每种装备进行按p的大小进行升序快排。以便之后的查找工作。

    2、保存min到Max之间的所有的的B的节点及他们所在行列数,便于之后查询。

    3、对min到Max之间的B[i]进行枚举,并进行更新。

    4、输出最大的值。

    #include <stdlib.h>
    #include <stdio.h>
    typedef struct Node
    {
    int bb;
    int p;
    }Node;
    typedef struct BID
    {
    int bb;//带宽值
    int row;//所在的行号
    int col;
    }BID;
    Node node[101][101];//保存节点
    BID B[10001];//保存需要枚举的带宽B值
    int comp(const void *a,const void *b)
    {
    BID* x=(BID*)a;
    BID* y=(BID*)b;
    if(x->bb==y->bb)
    {
    if(x->row==y->row)
    return x->col-y->col;
    return x->row-y->row;
    }
    return x->bb-y->bb;
    }
    int cmp(const void *a,const void *b)
    {
    return ((Node*)a)->p-((Node*)b)->p;
    }
    int main()
    {
    void search(int num,int index[]);
    int max[101];//保存每组的P最大值
    int index[101];//保存每行厂家的个数
    int n,num;
    int i,j,k;
    scanf("%d",&n);
    while(n-->0)//
    {
    int min=65535;//保存最小的P值
    int count=0;
    for(i=0;i<10001;i++)
    B[i].bb=0;
    scanf("%d",&num);//设备种数
    for(i=0;i<num;i++)//输入一组测试数据
    {
    scanf("%d",&index[i]);
    for(j=0;j<index[i];j++)//输入一行数据
    {
    scanf("%d %d",&node[i][j].bb,&node[i][j].p);
    if(node[i][j].bb>max[i])
    max[i]=node[i][j].bb;
    if(node[i][j].bb<min)
    min=node[i][j].bb;
    }
    }
    int Max=65535;//保存最大中的最小P值
    for(k=0;k<num;k++)
    if(max[k]<Max)
    Max=max[k];
    for(i=0;i<num;i++) //对各种厂家的设备按P从大到小的顺序升序排序
    qsort(node[i],index[i],sizeof(Node),cmp);
    for(i=0;i<num;i++)
    for(j=0;j<index[i];j++)
    if(node[i][j].bb>=min&&node[i][j].bb<=Max)
    {
    B[count].bb=node[i][j].bb;
    B[count].row=i;
    B[count++].col=j;
    }
    qsort(B,count,sizeof(BID),comp); //对B中的值按b为第一关键字,row为第二,cow为第三关键字升序排序
    search(num,index);
    }
    return 1;
    }
    void search(int num,int index[101])//按B[]中的顺序进行枚举,并不断更新
    {
    int k=0;
    int i,j;
    double result=0;
    while(B[k].bb)
    {
    double sum=0;
    if(k&&B[k].bb==B[k-1].bb&&B[k].row==B[k-1].row)
    {
    k++;
    continue;
    }
    int flag=0;
    for(i=0;i<num;i++)
    {
    if(i!=B[k].row)
    {
    for(j=0;j<index[i];j++)
    if(node[i][j].bb>=B[k].bb)//保证每种装备都有一件,否则不更新
    {
    sum=sum+node[i][j].p;
    flag=1;
    break;
    }
    if(flag)
    flag=0;
    else
    break;
    }
    }
    if(i==num)
    {
    double average;
    average=B[k].bb/(sum+node[B[k].row][B[k].col].p);//
    if(average>result)
    result=average;
    }
    k++;
    }
    printf("%.3lf\n",result);
    }

  • 相关阅读:
    %2d
    将块中的文字设置成属性,即实现块中文字可拖动的功能
    获得块参照的插入点方法
    排序
    将几个实体对象变成一个块
    对克隆实体的类型转换
    对实体的克隆
    递归-顺序输出任意正整数各位
    递归-汉诺塔
    递归-最大公约数
  • 原文地址:https://www.cnblogs.com/ltfbk/p/2578535.html
Copyright © 2011-2022 走看看