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 }

猜你喜欢

转载自www.cnblogs.com/tangwuling/p/10025925.html
今日推荐