提前声明:本题解不提供快捷目录,请耐心看完(一定要看到最后呀!!!)
懒得再写一遍题目了,直接看原题
其实这道题暴力枚举每个点就可以,话不多说,先上代码
#include<bits/stdc++.h>
using namespace std;
int n,m,p1,p2,s1,s2;
int l=0,h=0;//l表示龙的势力,r表示虎的势力
void place()//直接暴力就行
{
int cj=abs(l-h);//cj表示差距,龙虎势力值之的绝对值
if(l>h)//龙的势力大于虎的势力
{
for(int i=n;i>m;i--)//暴力枚举
{
int hh=h+s2*(i-m);//不能直接改h,用hh代替
if(cj>abs(hh-l))//判断两方势力差距是否更小
{
p2=i;
cj=abs(hh-l);//这里注意刷新差距
}
}
return;
}
if(h>l)//虎的势力大于龙的势力
{
for(int i=1;i<m;i++)//暴力枚举
{
int ll=l+s2*(m-i);
if(cj>abs(ll-h))
{
p2=i;
cj=abs(ll-h);
}
}
return;
}
}
int main()
{
cin>>n;
int a[n+5];//可以这样用变量定义数组 ,a存储每个点工兵数量
for(int i=1;i<=n;i++)
cin>>a[i];
cin>>m>>p1>>s1>>s2;
for(int i=1;i<m;i++)
l+=(m-i)*a[i];//求龙的势力
for(int i=n;i>m;i--)
h+=(i-m)*a[i];//求虎的势力
if(p1<m)//s1名工兵降落在龙方阵营
l+=(m-p1)*s1;
if(p1>m)//s1名工兵降落在虎方阵营
h+=(p1-m)*s1;
//否则降落在m点上,不用管
p2=m;//初始p2值为m
place();
cout<<p2;
return 0;
}
然后就挂了五个点......
到底是哪里出了问题
其实代码没问题,原因是没开longlong.......
虽然一个数int存的下,但加起来会超过int(在1e18~ 9e18之间,炸int了)
于是,开成longlong就过了,(我懒得一个一个改,全给他用替换改longlong了)
满分AC代码了解一下:(不要抄完代码就划走,后面的东西很重要)
#include<bits/stdc++.h>
#define lll long long //因为后面有定义的ll,所以只能define成lll(懒得打那么多遍long long)
using namespace std;
lll n,m,p1,p2,s1,s2;
lll l=0,h=0;//l表示龙的势力,r表示虎的势力
void place()//直接暴力就行
{
lll cj=abs(l-h);//cj表示差距,龙虎势力值之的绝对值
if(l>h)//龙的势力大于虎的势力
{
for(lll i=n;i>m;i--)//暴力枚举
{
lll hh=h+s2*(i-m);//不能直接改h,用hh代替
if(cj>abs(hh-l))//判断两方势力差距是否更小
{
p2=i;
cj=abs(hh-l);//这里注意刷新差距
}
}
return;
}
if(h>l)//虎的势力大于龙的势力
{
for(lll i=1;i<m;i++)//暴力枚举
{
lll ll=l+s2*(m-i);
if(cj>abs(ll-h))
{
p2=i;
cj=abs(ll-h);
}
}
return;
}
}
int main()
{
cin>>n;
lll a[n+5];//可以这样用变量定义数组 ,a存储每个点工兵数量
for(lll i=1;i<=n;i++)
cin>>a[i];
cin>>m>>p1>>s1>>s2;
for(lll i=1;i<m;i++)
l+=(m-i)*a[i];//求龙的势力
for(lll i=n;i>m;i--)
h+=(i-m)*a[i];//求虎的势力
if(p1<m)//s1名工兵降落在龙方阵营
l+=(m-p1)*s1;
if(p1>m)//s1名工兵降落在虎方阵营
h+=(p1-m)*s1;
//否则降落在m点上,不用管
p2=m;//初始p2值为m
place();
cout<<p2;
return 0;
}
哦,对了,你们有没有注意一个点
题目中说,如果存在多个编号同时满足最优,取最小的编号
但为什么我并没有特意避这个坑点而AC了呢
我们再来回顾程序:
if(l>h)//龙的势力大于虎的势力
{
for(lll i=n;i>m;i--)//暴力枚举
{
lll hh=h+s2*(i-m);//不能直接改h,用hh代替
if(cj>abs(hh-l))//判断两方势力差距是否更小
{
p2=i;
cj=abs(hh-l);//这里注意刷新差距
}
}
return;
}
if(h>l)//虎的势力大于龙的势力
{
for(lll i=1;i<m;i++)//暴力枚举
{
lll ll=l+s2*(m-i);
if(cj>abs(ll-h))
{
p2=i;
cj=abs(ll-h);
}
}
return;
}
这是程序的主枚举部分
我们先看龙的,i=1;i<m;i++;
也就是说从小到大依次枚举,并且cj>abs(ll-h)这块我没有加等号,则程序就自动判定小者优先,因为先判定了小的,后面与其相等的就判不上(这里再看不懂为什么就有点过分了)
再看虎的,i=n;i>m;i--,是从大到小判......
呵呵,是的,我似乎并没有避开这个坑点,但数据他没坑我呀,也就蒙混过关了(不要嫌我嘴欠:P)
但为了程序的严谨性,为了我们的正义感,我决定了:
#include<bits/stdc++.h>//就不加注释了,注释看前面
#define lll long long
using namespace std;
lll n,m,p1,p2,s1,s2;
lll l=0,h=0;
void place()
{
lll cj=abs(l-h);
if(l>h)
{
for(lll i=m+1;i<=n;i++)//这里改了哟
{
lll hh=h+s2*(i-m);
if(cj>abs(hh-l))
{
p2=i;
cj=abs(hh-l);
}
}
return;
}
if(h>l)
{
for(lll i=1;i<m;i++)
{
lll ll=l+s2*(m-i);
if(cj>abs(ll-h))
{
p2=i;
cj=abs(ll-h);
}
}
return;
}
}
int main()
{
cin>>n;
lll a[n+5];
for(lll i=1;i<=n;i++)
cin>>a[i];
cin>>m>>p1>>s1>>s2;
for(lll i=1;i<m;i++)
l+=(m-i)*a[i];
for(lll i=n;i>m;i--)
h+=(i-m)*a[i];
if(p1<m)
l+=(m-p1)*s1;
if(p1>m)
h+=(p1-m)*s1;
p2=m;
place();
cout<<p2;
return 0;
}
最后,总结坑点:
1,一定要用long long,不然会丢20分!(自己还不知道咋丢的)
2,枚举时一定从小到大枚举!
最后的最后,祝看到这里的老铁们rp++!
祝点赞关注的老铁们(akioi)做的全会,蒙的全对!
感谢各位大佬的耐心观看!