题目目录: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; }