ACMC5

A - Park Lighting CodeForces - 1358A

每个路灯最多照亮两个区域,则使尽可能多的路灯这样。每行用行2灯照亮,若每行有一个区域空余,则
用竖2路灯照亮
#include <bits/stdc++.h>
using namespace std;

int main()
{
   int n;
   cin>>n;
   while(n--)
   {
     int a,b;
     cin>>a>>b;
     int sum1=a/2;
     if(a%2!=0)
     {
         sum1*=b;
         sum1+=b%2+b/2;
     }
     else
     {
         sum1*=b;
     }
     
     int sum2=b/2;
     if(b%2!=0)
     {
         sum2*=a;
         sum2+=a%2+a/2;
     }
     else
     {
         sum2*=a;
     }
     
     cout<<min(sum1,sum2)<<endl;
   }
   //system("pause");
   return 0;
}

B - Maria Breaks the Self-isolation CodeForces - 1358B

先排序,若同时招i个人,则arr[i-1]处应大于i,找到最大i即可
#include <bits/stdc++.h>
using namespace std;

int main()
{
     int n;
   cin>>n;
   while(n--)
   {
       int a;
       cin>>a;
       int sum=1;
       int arr[a];
       for(int i=0;i<a;i++)
       {
           cin>>arr[i];
       }
       sort(arr,arr+a);
       for(int i=0;i<a;i++)
       {
           if(arr[i]<=i+1)
           {
               sum=i+2;
           }
       }
       cout<<sum<<endl;
   }
   //system("pause");
   return 0;
}

C - Celex Update CodeForces - 1358C

分析可知,路径和有一个最大值和最小值,且之间的值都存在,则最大-最小+1即是结果。而可以发现,先走下,
走完再走右是最大值,先走右,最后下则最小。差为行差×列差
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    int n;
   cin>>n;
   while(n--)
   {
       ll a,b,c,d;
       int cc,dd,aa;
       cin>>a>>b>>c>>d;
       ll sum=1;
       sum+=(c-a)*(d-b);
       cout<<sum<<endl;
   }
   //system("pause");
   return 0;
}

D - The Best Vacation CodeForces - 1358D

分析可知应用尺取法,枚举终点推出起点计算拥抱合取最大即可,但存在2个问题:
1.不能把每个月份的具体每天拥抱次数记下来。(数量太大,数组存不下)
2.可以取不同年份的连续月(会出现回环)
对应的解决方法:
1.分析可知,最大拥抱数一定以某月的最后一天为终点,则可以只记录每月天数和每月总拥抱次数(使用时:如
该月有5天,取两天,则从15的合中刨去15-2的和)(另外,月份如果记录为前i个月的和,则ij相减就
可以得到i到j月的总天数,拥抱数也可以如此记录)
2.将每月天数存两遍(从12n),这样终点从2n遍历至n时,推出的起点不用取环

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2e6+100;
LL a[N],sum[N];
LL cal(LL l,LL r)
{
	return (l+r)*(r-l+1)/2;
}
int main()
{
	int n;
	LL x;
	cin>>n>>x;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		a[i+n]=a[i];//记录两遍天数,这样不用计算回环
		sum[i]=sum[i+n]=cal(1,a[i]);//每一个月拥抱的总次数
	}
	for(int i=1;i<=2*n;i++)
	{
		a[i]+=a[i-1];
		sum[i]+=sum[i-1];
	}
	LL ans=0;
	for(int i=2*n,j=2*n;i>n;i--)//枚举终点
	{
		while(j>0&&a[i]-a[j]<=x)
			j--;
		ans=max(ans,sum[i]-sum[j]-cal(1,a[i]-a[j]-x));
	}
	cout<<ans<<endl;
   //system("pause");
    return 0;
}
启示:1.利用两遍记录防止回环 2.记录时,数组第i个位置记录前i个和,这样可以快速求某区间数组的和

待补充ing

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值