P5016 龙虎斗 题解
这题真是*到家了QAQ
我在考场上调了将近75min,总算过了大样例。
首先,我们可以简化这一题,这道题的本质就是让我们找出一个点p2,往那个点上面加上s2个单位的重量,使得以m为中的两边的权值和的差尽量的小。
其中权值和的计算方法是:对于第i号节点(i!=m),令mi为它的权值,则有mi=|i-m|*ai,其中ai为输入时的该兵营的兵力总量。
明白了这一点后,剩下的就好办了。我们只要用一个bl_l来存储轩轩一方的权值总和,用bl_r来存储凯凯一方的权值总和;(注意,要用bl_l和bl_r 要开unsigned long long)
最后,计算cha = |bl_l-bl_r|;再用cha 来除以输入的s2(你手中拥有的兵力),就是answer 了
此时,还有一个要注意的地方,如果answer超过了n或者小于了1,那么就要相应地将其变成n或者1,因为答案必须在1~n之间。
而且answer需要四舍五入。
下面是代码:
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 #define ll unsigned long long 5 int a[100005],n,m,p1,s1,s2; 6 ll bl_l,bl_r; 7 int main() 8 { 9 // freopen("fight.in","r",stdin); 10 // freopen("fight.out","w",stdout); 11 scanf("%d",&n); 12 for (int i=1;i<=n;i++) 13 scanf("%d",&a[i]); 14 scanf("%d %d %d %d",&m,&p1,&s1,&s2); 15 a[p1]+=s1; 16 for (int i=1;i<m;i++) bl_l+=(ll)(m-i)*a[i]; 17 for (int i=(int)m+1;i<=n;i++) bl_r+=(ll)(i-m)*a[i]; 18 // printf("%llu %llu\n",bl_l,bl_r); 19 if (bl_l==bl_r) printf("%d\n",m); 20 else if (bl_l<bl_r) 21 { 22 ll cha=bl_r-bl_l; 23 // printf("%lld\n",cha); 24 double mm=(double)cha/(double)s2; 25 // printf("%lf\n",mm); 26 ll dis_m=(mm*10+5)/10; 27 if (m-dis_m<=0) printf("1\n"); 28 else printf("%lld\n",m-dis_m); 29 } 30 else 31 { 32 ll cha=bl_l-bl_r; 33 // printf("%lld\n",cha); 34 double mm=(double)cha/(double)s2; 35 // printf("%lf\n",mm); 36 ll dis_m=(mm*10+5)/10; 37 if (m+dis_m>n) printf("%d\n",n); 38 else printf("%lld\n",m+dis_m); 39 } 40 fclose(stdin); 41 fclose(stdout); 42 return 0; 43 }