1.田地丈量
问题描述
西西艾弗岛上散落着 n 块田地。每块田地可视为平面直角坐标系下的一块矩形区域,由左下角坐标 (x1,y1) 和右上角坐标 (x2,y2) 唯一确定,且满足 x1<x2、y1<y2。这 n 块田地中,任意两块的交集面积均为 0,仅边界处可能有所重叠。
最近,顿顿想要在南山脚下开垦出一块面积为 a×b 矩形田地,其左下角坐标为 (0,0)、右上角坐标为 (a,b)。试计算顿顿选定区域内已经存在的田地面积。
输入格式
从标准输入读入数据。
输入共 n+1 行。
输入的第一行包含空格分隔的三个正整数 n、a 和 b,分别表示西西艾弗岛上田地块数和顿顿选定区域的右上角坐标。
接下来 n 行,每行包含空格分隔的四个整数 x1、y1、x2 和 y2,表示一块田地的位置。
输出格式
输出到标准输出。
输出一个整数,表示顿顿选定区域内的田地面积。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,a,b;
cin>>n>>a>>b;
int i=0;
//左下角和右上角的坐标
int x1,y1,x2,y2;
//mj表示面积
int mj=0;
int x3,y3,x4,y4;
for(i=1;i<=n;i++){
cin>>x1>>y1>>x2>>y2;
if(y1>=b){
mj+=0;
}
if(y1<b){
if(x1>=a){
mj+=0;
}
else if(x1<a){
x3=max(x1,0);
y3=max(y1,0);
x4=min(x2,a);x4=max(0,x4);
y4=min(y2,b);y4=max(0,y4);
mj+=(x4-x3)*(y4-y3);
}
}
}
cout<<mj;
return 0;
}
2.垦田计划
问题描述
顿顿总共选中了 n 块区域准备开垦田地,由于各块区域大小不一,开垦所需时间也不尽相同。据估算,其中第 i 块(1≤i≤n)区域的开垦耗时为 ti 天。这 n 块区域可以同时开垦,所以总耗时 tTotal 取决于耗时最长的区域,即:tTotal=max{t1,t2,⋯,tn}
为了加快开垦进度,顿顿准备在部分区域投入额外资源来缩短开垦时间。具体来说:
-
在第 i 块区域每投入 ci 单位资源,便可将其开垦耗时缩短 1 天;
-
耗时缩短天数以整数记,即第 i 块区域投入资源数量必须是 ci 的整数倍;
-
在第 i 块区域最多可投入 ci×(ti−k) 单位资源,将其开垦耗时缩短为 k 天;
-
这里的 k 表示开垦一块区域的最少天数,满足 0<k≤min{t1,t2,⋯,tn};换言之,如果无限制地投入资源,所有区域都可以用 k 天完成开垦。
现在顿顿手中共有 m 单位资源可供使用,试计算开垦 n 块区域最少需要多少天?
输入格式
从标准输入读入数据。
输入共 n+1 行。
输入的第一行包含空格分隔的三个正整数 n、m 和 k,分别表示待开垦的区域总数、顿顿手上的资源数量和每块区域的最少开垦天数。
接下来 n 行,每行包含空格分隔的两个正整数 ti 和 ci,分别表示第 i 块区域开垦耗时和将耗时缩短 1 天所需资源数量。
输出格式
输出到标准输出。
输出一个整数,表示开垦 n 块区域的最少耗时。
二分查找进行优化
#include<bits/stdc++.h>
using namespace std;
//stl
typedef pair<int,int> pit;
const int maxn=100010;
pit land[maxn];
int n,m,k;
int m1=m;
//从小到大排序需要用到的参数函数
bool cmp(pit l1,pit l2)
{
return l1.first<l2.first;
}
//判断当前天数是否合规
dcs(int day){
int i=0;
m1=m;
for(i=n-1;i>=0;i--){
if(land[i].first>day){
m1-=(land[i].first-day)*land[i].second;
}
}
if(m1==0) return 0;
if(m1<0) return -1;
if(m1>0) return 1;
}
//二分查找
int binsch(){
int low=k,high=land[n-1].first;
int mid;
int mind=land[n-1].first;
while(low<=high){
mid=(low+high)>>1;
if (dcs(mid)==0){
return mid;
}
else if(dcs(mid)<0){
low=mid+1;
}
else if(dcs(mid)>0){
mind=min(mind,mid);
high=mid-1;
}
}
return mind;
}
int main(){
scanf("%d%d%d",&n,&m,&k);
int i=0;
for(i=0;i<n;i++){
cin>>land[i].first>>land[i].second;
}
sort(land,land+n,cmp);
cout<<binsch()<<endl;
return 0;
}
暴力解题(70分)
#include<bits/stdc++.h>
using namespace std;
const int maxn=1000010;
int n,m,k;
typedef struct{
int t;
int c;
}tiandi;
tiandi td[maxn];
int ts;
//排序
void maopao(tiandi *td){
int i=0;
int j=0,temp=0;
for(i=1;i<=n;i++){
for(j=1;j<=n-i;j++){
if(td[j].t <td[j+1].t){
temp=td[j].t;
td[j].t=td[j+1].t;
td[j+1].t=temp;
temp=td[j].c;
td[j].c=td[j+1].c;
td[j+1].c=temp;
}
}
}
}
int main(){
cin>>n>>m>>k;
int i=0;
for(i=1;i<=n;i++){
cin>>td[i].t >>td[i].c ;
}
maopao(td);
ts=td[1].t ;
//每次减1
while(td[1].t >k && m>0){
int j=0;
for(j=1;j<=n && td[j].t ==ts;j++){
td[j].t --;
m-=td[j].c ;
}
ts--;
}
if(m<0){
cout<<ts+1<<endl;
}
else{
cout<<ts<<endl;
}
return 0;
}