uva 12124

分类: 高效搜索,二分

题意: 给定电脑各种配件,每个配件有价格和品质因子,在给定钱数b的前提下,每种配置选一个,使得最小品质因数最大,保证有解

输入: 测试组数T, 钱数b,配件个数n,以下n行为每个配件的分类, 名称, 价格, 品质因子

输出: 最大的品质因数方案的品质因子

 

核心: 搜索答案,按照品质因子个数进行二分查找 

         二分查找是个蛮有趣的问题,恰好这个题里面一些细节处理不好是通不过测试的。

        ① 基本二分:

    int right = upper;
    while(left < right)
    {
        int mid = (left + right) / 2;
        if(A[mid] == num)
            return mid;
        else if(A[mid] < num)
            left = mid + 1;
        else
            right = mid;
    }
    return -1;

         找一个确定的数num,那么查找的结果范围是什么呢(解空间),[left, right),因为left 不可能是 right

         ② 查找lower_bound   

while(left < right)
{
    mid = (left + right) / 2;
   if(A[mid] >= num)
        right = mid;
   else
        left = mid + 1;
}
return left;

         找到一个满足条件第一个

         ③查找upper_bound

while(left < right)
{
    mid = (left + right) / 2;
   if(A[mid] <= num)
        left = mid + 1;
   else
        right= mid;
}
return left;

         返回满足条件的最后一个值的后一位

         ②和③合并求出区间[L, R) LRJ入门经典上有相关的叙述

 换一种写法:

          基本二分:     

    while(left < right)
    {
        int mid = left + (right - left + 1) / 2;
        if(A[mid] == num)
            return mid;
        else if(A[mid] < num)
            left = mid + 1;
        else
            right = mid;
    }
    return -1;

         解空间为(left, Right]

        

uva 12124的不同写法

        

#include <iostream>
#include <vector>
#include <map>
#include <list>
#include <set>
#include <deque>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <cstdio>
#include <iomanip>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <string>
#include <sstream>
#include <cstring>
#include <queue>
using namespace std;

///宏定义
const int  INF = 990000000;
const int MAXN = 1062;
const int maxn = MAXN;
///全局变量 和 函数
typedef int LL;
LL T;
LL n, b;
struct comp
{
    LL price, quality;
    bool operator < (const comp& T) const
    {
        if (quality < T.quality)
            return true;
        else if (quality == T.quality)
            return price < T.price;
        else
            return false;
    }
};

vector<comp>  inputData[maxn];
map<string, LL> id;
LL cnt;

bool isOk(LL curQua)
{
    LL cost = 0;
    for (LL i = 0; i < cnt; i++)
    {
        LL cheapest = b + 1;
        //挑选满足品质因子且最便宜的配件
        for (LL j = 0; j < inputData[i].size(); j++)
        {
            if (inputData[i][j].quality >= curQua)
            {
                if (inputData[i][j].price < cheapest)
                    cheapest = inputData[i][j].price;
            }
        }
        if (cheapest == b + 1)
            return false;
        cost += cheapest;
        if (cost > b)
            return false;
    }
    return true;
}

LL findAns(LL lowQua, LL highQua)
{
    while (lowQua < highQua)
    {
        LL mid = (lowQua + highQua) / 2;
        if (isOk(mid))
        {
            lowQua = mid + 1;
        }
        else
            highQua = mid;
    }
    return lowQua;
}
/*
LL findAns(LL lowQua, LL highQua)
{
    while (lowQua < highQua)
    {
        LL mid = lowQua + (highQua - lowQua + 1) / 2;
        if (isOk(mid))
        {
            lowQua = mid;
        }
        else
            highQua = mid - 1;
    }
    return lowQua;
}

*/

LL myID(string s)
{
    if (!id.count(s))
        id[s] = cnt++;
    return id[s]; //注意是否存在然后返回
}


int main()
{
    ///变量定义
    cin >> T;
    int cases = 1;
    while (T--)
    {
        LL minQua, maxQua;
        minQua = INF;
        maxQua = -1;
        cnt = 0;
        cin >> n >> b;
        for (LL i = 0; i < n; i++)
            inputData[i].clear();
        id.clear();
        for (LL i = 0; i < n; i++)
        {
            string type, name;
            LL tmpPice, tmpQua;
            cin >> type >> name >> tmpPice >> tmpQua;
            LL curPos;
            //返回种类映射
            curPos = myID(type);
            comp tempComp;
            tempComp.price = tmpPice;
            tempComp.quality = tmpQua;
            inputData[curPos].push_back(tempComp);
            if (tmpQua > maxQua)
                maxQua = tmpQua;
            if (tmpQua < minQua)
                minQua = tmpQua;
        }    
        LL ans = findAns(minQua, maxQua + 1); //注意是要加1的!,因为采用[...), 找到的为后一位的值
        cout << ans - 1 << endl; 
    }
    ///结束
    return 0;
}

 

         

posted on 2013-09-22 17:54  小书包_Ray  阅读(244)  评论(0编辑  收藏  举报

导航