易错点:
- abs()在开long long时必须重写.
- 在答案相同时优先选择编号较小的.
- 开long long.
#include<cstdio> #include<iostream> #include<cmath> #define ll long long using namespace std; const int MAXN=5e6; ll c[MAXN];//兵营的原始兵量 ll m,n; ll getASum(){//获取A阵营的总气势 ll ASum=0; for(int i=1;i<=m-1;i++){ ASum+=c[i]*abs(m-i); } return ASum; } ll getBSum(){//获取B阵营的总气势 ll BSum=0; for(int i=m+1;i<=n;i++){ BSum+=c[i]*abs(m-i); } return BSum; } bool isFromA(ll x){//判断是否属于A阵营 return (x<m); } ll absK(ll val){ if(val>=0)return val; return -val; } int main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>c[i]; } //中立势力 //免费赠送兵位置 数量 int p1,s1, s2;//自己的兵量 cin>>m>>p1>>s1>>s2; c[p1]+=s1;//免费送兵 ll Asum=0,Bsum=0;//两个阵营的总气势 Asum=getASum(),Bsum=getBSum(); ll ansIndex,ansDelta;//当前位置和当前气势差值 ansIndex=m,ansDelta=absK(Asum-Bsum); for(int i=1;i<=n;i++){//尝试在每个兵营加气势 if(i==m)continue; bool isA=isFromA(i);//是否属于A阵营 if(isA){//如果属于A阵营 ll newAsum=Asum+s2*absK(m-i);//A阵营新总值 ll newDelta=absK(newAsum-Bsum); if(newDelta<ansDelta){//能更新 ansDelta=newDelta; ansIndex=i; }else if(newDelta==ansDelta&&i<ansIndex){ ansIndex=i; } }else{ ll newBsum=Bsum+s2*absK(m-i); ll newDelta=absK(Asum-newBsum); if(newDelta<ansDelta){ ansDelta=newDelta; ansIndex=i; }else if(newDelta==ansDelta&&i<ansIndex){ ansIndex=i; } } } printf("%lld ",ansIndex); return 0; }