题目目录:I F
I题 Intervals on the Ring(环上的间隔)
题目大意:给出一个1—n组成的闭环,每个大小相邻的数字相连,并且1和n相连。我们用[l,r]描述环上的区间,如果l≤r,区间包含l—r之间的数,如果l>r,区间包含l—n和1—r之间的数。现在给出m个不相交的区间,现在要构造k个区间使得它们的交集是m个区间的并集。如果不存在,输出-1,存在输出k≤2000的任意满足条件的k个构造区间。

思路:首先我们应该知道:区间【a+1,a】(0≤a≤n-1)包含了1~n中的所有元素,区间【a+b,a】(b>1)除去了(a,a+b)之间的整数。假如我们将m个区间在环上画出,会发现相邻区间要么相邻(上一区间的右端点right1+1==下一区间的左端点left2),要么中间间隔数字(即这是要被去除的数字)。此时我们只要构造所有的区间【left2,right1】即可得到想要的交集。此时构造的区间数会等于m的个数。

#include <bits/stdc++.h>
using namespace std;

struct node{
    int l,r;
}inv[1004];

bool cmp(node a,node b){
    return a.l<b.l;
}

int main(){
    int t;
    cin>>t;
    while(t--){
        int n,m;
        cin>>n>>m;
        for(int i=1;i<=m;i++) cin>>inv[i].l>>inv[i].r;
        sort(inv+1,inv+m+1,cmp);
        cout<<m<<endl;
        for(int i=1;i<=m;i++){
            if(i==1) cout<<inv[1].l<<" "<<inv[m].r<<endl;
            else cout<<inv[i].l<<" "<<inv[i-1].r<<endl;
        }    
    }
    return 0;
} 

F题 Hamburger Steak
题目大意:给出m个锅和n个牛排。第i个汉堡需要t[i]分钟,一块牛排可以在一个锅里煎t[i]分钟或者分在两个锅里共煎t[i]分钟。可以用不同的锅同时煎好几块牛排,但一个锅里最多煎一块牛排,并且一块牛排在某一时刻只能在一个锅里煎。现在要输出一种方案使得煎熟所有牛排用的时间最少。输出n行,第n行是第n块牛排的煎法。第一个数字输出牛排在几个锅里煎(1或2),然后输出用到的锅的编号,并且牛排在锅中煎的时间区间。依照字典序输出。

思路:先找出所需要的最长的用锅时间up,然后保证每个锅的煎牛排的时间不超过up即可。要注意的是,当平均数是小数点要向上取整,这里采用了(sum+m-1)/m的方法。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=100010;
int n,m;
LL a[N],up;
int main(){
    cin>>n>>m;
    LL sum=0;
    for(int i=0;i<n;i++){
        cin>>a[i];
        sum+=a[i];//求所有牛排需要的时间总和 
        up=max(up,a[i]);//找出耗时最长的牛排 
    }
    up=max(up,(sum+m-1)/m);//这表示当总和不能整除锅数时,在原最大时间上+1 
    int k=1;
    LL t=0; 
    for(int i=0;i<n;i++){
        if(t+a[i]<=up){
            cout<<1<<" "<<k<<" "<<t<<" "<<t+a[i]<<endl;
            t+=a[i];
            if(t==up){
                k++;
                t=0;
            }
        }
        else {
            cout<<2<<" "<<k+1<<" "<<0<<" "<<t+a[i]-up<<" "<<k<<" "<<t<<" "<<up<<endl;
            k++;
            t=t+a[i]-up;
        }
    }
    return 0;
}