[codeforces 1334C] Circle of Monsters 公式推导+变环形关系为直线关系+前缀和

Codeforces Round #632 (Div. 2)   比赛人数14824

[codeforces 1334C]   Circle of Monsters   公式推导+变环形关系为直线关系+前缀和

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

在线测评地址https://codeforces.com/contest/1334/problem/C

Problem Lang Verdict Time Memory
C - Circle of Monsters GNU C++17 Accepted 280 ms 18800 KB

比赛中一度以为该题做不出,不过,没有放弃,拿出纸笔,写写算算,不经意间,发现了该题的解决办法。

样例数据手工模拟如下

Input:
1
3
7 15
2 14
5 3
Output:
6

a1=7 b1=15
a2=2 b2=14
a3=5 b3=3

因(a2-b1)=(2-15)<0,故取值为a2-b1=0
因(a3-b2)=(5-14)<0,故取值为a3-b2=0
从位置1出发:消耗的子弹=a1+(a2-b1)+(a3-b2)=7+0+0=7

因(a3-b2)=(5-14)<0,故取值为a3-b2=0
因(a1-b3)=(7-3)>=0,故取值为a1-b3=4
从位置2出发:消耗的子弹=a2+(a3-b2)+(a1-b3)=2+0+4=6

因(a1-b3)=(7-3)>=0,故取值为a1-b3=4
因(a2-b1)=(2-15)<0,故取值为a2-b1=0
从位置3出发:消耗的子弹=a3+(a1-b3)+(a2-b1)=5+4+0=9

可以看到规律了:
a1+(a2-b1)+(a3-b2)
a2+(a3-b2)+(a1-b3)
a3+(a1-b3)+(a2-b1)
这3组数据中取最大值


环形的数据关系处理起来比较麻烦,怎么办呢,化成直线的数据关系,就容易处理了

接着上面的数据,继续分析
将数组由长度n串接为2*n,如何串接,请看如下分析。
位置         1  2      3      4      5              6
a           a1 a2     a3     a1     a2             a3
b           b1 b2     b3     b1     b2             b3
c              a2-b1 a3-b2  a1-b3  a2-b1          a3-b2
前缀和sum    0  c2   c2+c3 c2+c3+c4 c2+c3+c4+c5   c2+c3+c4+c5+c6        

a1+(a2-b1)+(a3-b2)=a1+(sum[3]-sum[1])
a2+(a3-b2)+(a1-b3)=a2+(sum[4]-sum[2])
a3+(a1-b3)+(a2-b1)=a3+(sum[5]-sum[3])

AC代码如下

#include <cstdio>
#include <algorithm>
#define maxn 600010
#define LL long long
using namespace std;
LL a[maxn],b[maxn],c[maxn],sum[maxn];
int main(){
	int t,n,i;
	LL mn;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		mn=1e18;//超出int范围的赋值
		for(i=1;i<=n;i++)scanf("%lld%lld",&a[i],&b[i]);
		for(i=n+1;i<=2*n;i++)a[i]=a[i-n],b[i]=b[i-n];//变环形为直线
		for(i=2;i<=2*n;i++)c[i]=((a[i]>b[i-1])?(a[i]-b[i-1]):0);//爆炸对应的子弹消耗
		sum[1]=0;
		for(i=2;i<=2*n;i++)sum[i]=sum[i-1]+c[i];//前缀和
		for(i=1;i<=n;i++)
			mn=min(mn,a[i]+sum[i+n-1]-sum[i]);
		printf("%lld\n",mn);
	}
	return 0;
}
发布了660 篇原创文章 · 获赞 562 · 访问量 48万+

猜你喜欢

转载自blog.csdn.net/mrcrack/article/details/105446749
今日推荐