zoukankan      html  css  js  c++  java
  • Code Jam 2017 Round 1A Problem B. Ratatouille

    传送门

    分析

    首先把(package)的克数 $Q_{ij}$ 转化成区间 $[lceil Q_{ij}/(1.1 r_i ) ceil, lfloor Q_{ij}/(0.9 r_i) floor]$。可以通过将分子、分母同乘10来避免精度问题。注意某个包对应的区间可能为空,比如 $Q_{ij}=13, r_i=10$。然后将每种成分(ingredient)的包对应的区间按左右端点双关键字从小到大排序(用std::pair<int,int>表示区间)。考虑 $n$ 个最小的区间,两两比较,若不相交则将较小的区间删除(该区间对应的包不可能存在于任何 kit 中)。重复此删除过程,直到最小的 $n$ 个区间交集不为空。用这 $n$ 个区间对应的包组成一个 kit。

    这个做法的正确性可通过如下性质证明:

    对应同一成分的两区间 $a$、$b$,若 $a subset b$ 则 $a$、$b$ 的左右两端点至少有一个重合。

    Implementation

    #include <bits/stdc++.h>
    using namespace std;
    int T;
    int cas;
    
    const int N=55;
    int r[N];
    
    int q[N][N];
    
    
    using P=pair<int,int> ;
    
    
    
    
    int main(){
        for(cin>>T; T--; ){
            printf("Case #%d: ", ++cas); // !注意输出格式
            ///////////////////////////////////////
            int  n, p;
            cin >> n >> p;
    
            priority_queue<P, vector<P>, greater<P>> que[N];
    
            for(int i=0; i<n; i++)
                cin >> r[i];
    
            for(int i=0; i<n; i++)
                for(int j=0; j<p; j++){
                    cin >> q[i][j];
                    int mi=10*q[i][j]/(11*r[i])+bool(10*q[i][j]%(11*r[i]));
                    int ma=q[i][j]*10/(9*r[i]);
                    if(mi>ma) continue;
                    que[i].push({mi, ma});
                    // cout << mi <<' ' << ma<<endl;
                }
    
            // for(int i=0; i<n; i++){
            //     auto x=que[i].top();
            //     cout << x.first<<' '<< x.second << endl;
            // }
            int res=0;
    
            for(;;){
                bool flag=true;
                for(int i=0; i<n; i++)
                    if(que[i].empty()){
                        flag=false;
                        break;
                    }
    
                if(!flag) break;
    
                bool f=true;
                for(int i=0; i<n; i++){
                    for(int j=i+1; j< n; j++){
                        auto a=que[i].top(), b=que[j].top();
                        if(a.first>b.second){
                            que[j].pop();
                            f=false;
                            break;
                        }
                        if(b.first>a.second){
                            que[i].pop();
                            f=false;
                            break;
                        }
                    }
                    if(f==false) break;
                }
    
                if(f==false)
                    continue;
    
                res++;
    
                for(int i=0; i<n; i++)
                    que[i].pop();
            }
    
    
            cout << res<<endl;
    ////////////////////////////////////////////////////////
        }
        return 0;
    
    }
    
  • 相关阅读:
    Java设计模式之装饰模式
    学习Emacs系列教程(二):导航
    Android ProgressDialog 延时消失
    java设计模式装饰模式
    Java 字节流和字符流的相互转换
    emacs配置颜色主题
    Android ProgressDialog的使用
    个人管理 时间管理GTD流程图
    jQuery - 列表控件推荐
    WPF - 模板查看工具:Show Me The Template及如何查看第三方主题
  • 原文地址:https://www.cnblogs.com/Patt/p/6714463.html
Copyright © 2011-2022 走看看