P5016 龙虎斗
思路:定义一个一维数组,存储每个兵营所含的人数,假设这个数组为a数组,100%的数据满足 n≤10^5;所以 a[100010];然后,再求出龙虎双方的势力:
1 for(int i=1;i<m;++i) 2 { 3 p+=(m-i)*a[i]; 4 } 5 for(int i=m+1;i<=n;++i) 6 { 7 q+=(i-m)*a[i]; 8 }
p代表龙方的势力,q代表虎方的势力,稳妥一些,开long long比较好;
然后再求出两方的势力差(要正数,用abs函数取绝对值就可以)然后就是从1到n循环一次,循环时,我分成了三种情况:
1 for(int i=1;i<=n;++i) 2 { 3 if(i<m) 4 { 5 p+=s*(m-i); 6 w=abs(p-q); 7 if(w<t) 8 { 9 t=w; 10 ans=i; 11 } 12 p=p1; 13 } 14 if(i==m) 15 { 16 w=abs(p-q); 17 if(w<t) 18 { 19 t=w; 20 ans=i; 21 } 22 } 23 if(i>m) 24 { 25 q+=s*(i-m); 26 w=abs(p-q); 27 if(w<t) 28 { 29 t=w; 30 ans=i; 31 } 32 q=q1; 33 } 34 }
t为两方的势力差+1,p1和q1分别为p和q的备份。当i<m时,就相当于增加龙方的势力,然后将它所增加的势力算出来,加到p上,再计算p与q的差,判断相比于之前是否差值变小,变小的话就将t更新为现在的差,并记录数组的位置。另外两种情况也类似。这样跑一遍,ans就是最终的答案。
在此之前我还进行了一次特判,如果我手里的工兵为0的话,就直接输出1,因为没有工兵的话改变不了两方的差值,并且输出要求如果存在多个编号同时满足最优,取最小的编号。
完整代码:
1 #include<iostream> 2 #include<cmath> 3 using namespace std; 4 int long long a[100010]; 5 int main() 6 { 7 long long n,p=0,q=0,p1,q1,ans,w,t; 8 cin>>n; 9 for(int i=1;i<=n;++i) 10 { 11 cin>>a[i]; 12 } 13 long long m,z,k,s; 14 cin>>m>>z>>k>>s; 15 if(s==0) 16 { 17 cout<<"1"; 18 return 0; 19 } 20 a[z]+=k; 21 for(int i=1;i<m;++i) 22 { 23 p+=(m-i)*a[i]; 24 } 25 for(int i=m+1;i<=n;++i) 26 { 27 q+=(i-m)*a[i]; 28 } 29 p1=p,q1=q; 30 t=abs(p-q)+1; 31 for(int i=1;i<=n;++i) 32 { 33 if(i<m) 34 { 35 p+=s*(m-i); 36 w=abs(p-q); 37 if(w<t) 38 { 39 t=w; 40 ans=i; 41 } 42 p=p1; 43 } 44 if(i==m) 45 { 46 w=abs(p-q); 47 if(w<t) 48 { 49 t=w; 50 ans=i; 51 } 52 } 53 if(i>m) 54 { 55 q+=s*(i-m); 56 w=abs(p-q); 57 if(w<t) 58 { 59 t=w; 60 ans=i; 61 } 62 q=q1; 63 } 64 } 65 cout<<ans; 66 return 0; 67 }