学大佬的暴力打表找规律,大佬打的表看不懂,自己打了一份。先看看表
当a=8 b=9的时候,规律很明显了
当a=8 b=8的时候规律是一样的
经过测试当a<=b的时候,规律相同
当a>b的时候规律发生变化,经过测试,当a>b && a<2*b 的时候规律相同
当 a>= 2b 的时候,又一个规律
把坐标轴分成四个部分,用那四个零点当原点,判断终点应该对应哪个原点
现在规律总结一下:
1.当a<=b的时候,答案就是终点到原点的水平距离和垂直距离中最大的那个值乘a
2.当a>b && a<=2b 答案是终点到原点的水平距离和垂直距离中最大的值乘b加上最小的值乘b-a
3.当a>=2b 答案是终点到原点的水平距离和垂直距离之和乘b
接下来是我的打表代码,是用bfs打的
#include
#include
#include
#include
#include
#include
#include
#include
typedef long long ll;
using namespace std;
const ll mod=998244353;
const int maxn=1e6+100;
int mp[1000][1000][4],vis[1000][1000][4];
int xx[5][5]={{0,1},{0,-1},{-1,0},{1,0}};
int a,b;
struct nn
{
int x,y,k;
nn(){}
nn(int x,int y,int k):x(x),y(y),k(k){}
};
int check(int k,int i)
{
if(k==0 && i==0)return 0;
if(k==1 && i==2)return 0;
if(k==2 && i==1)return 0;
if(k==3 && i==3)return 0;
return 1;
}
int getnexk(int i)
{
if(i==0)return 2;
if(i==1)return 0;
if(i==2)return 3;
if(i==3)return 1;
}
int getcost(int k,int nexk)
{
if(k==nexk)return b;
if(k==0 && nexk==3)return a;
if(k==1 && nexk==0)return a;
if(k==2 && nexk==1)return a;
if(k==3 && nexk==2)return a;
return 0;
}
void bfs()
{
queue<nn>q;
q.push(nn(500,500,0));
int cnt=0;
while(!q.empty()){
nn now=q.front();
q.pop();
for(int i=0;i<4;i++){
int x=now.x+xx[i][0];
int y=now.y+xx[i][1];
if(check(now.k,i)==0)continue;
int nexk=getnexk(i);
int cost=getcost(now.k,nexk);
if(abs(500-x)>10 || abs(500-y)>10)continue;
if(vis[y][x][nexk]==0){
mp[y][x][nexk]=mp[now.y][now.x][now.k]+cost;
vis[y][x][nexk]=1;
q.push(nn(x,y,nexk));
}
else if(mp[y][x][nexk]>mp[now.y][now.x][now.k]+cost){
mp[y][x][nexk]=mp[now.y][now.x][now.k]+cost;
q.push(nn(x,y,nexk));
}
}
}
// cout<
for(int i=492;i<=509;i++){
for(int j=492;j<=509;j++){
if(i==500 && j==500)printf("%3d",-1);
else
printf("%3d",min(min(mp[i][j][0],mp[i][j][1]),min(mp[i][j][2],mp[i][j][3])));
}cout<<endl;
}
}
int main() {
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
scanf("%d%d",&a,&b);
bfs();
return 0;
}
接下来是我的ac代码,写的有点麻烦,但是当时为了找规律没管他
#include
#include
#include
#include
#include
#include
#include
#include
typedef long long ll;
using namespace std;
const ll mod=998244353;
const int maxn=1e6+100;
ll a,b,x,y;
int jud()
{
if(x>=1 && y>=0)return 1;
if(x<=0 && y>=0)return 2;
if(x<=0 && y<=-1)return 3;
if(x>=1 && y<=-1)return 4;
}
ll solve1(ll c,ll d)
{
ll len=max(labs(x-c),labs(y-d));
return len*a;
}
ll solve2(ll c,ll d)
{
return max(labs(x-c),labs(y-d))*b+min(labs(x-c),labs(y-d))*(a-b);
}
ll solve3(ll c,ll d)
{
return (labs(x-c)+labs(y-d))*b;
}
int main() {
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int t;
scanf("%d",&t);
while(t--){
scanf("%lld%lld%lld%lld",&a,&b,&x,&y);
ll ans=0;
int xiang=jud();
if(a<=b){
if(xiang==1)ans=solve1(1,0);
if(xiang==2)ans=solve1(0,0);
if(xiang==3)ans=solve1(0,-1);
if(xiang==4)ans=solve1(1,-1);
}
else if(a>b && a<2*b){
if(xiang==1)ans=solve2(1,0);
if(xiang==2)ans=solve2(0,0);
if(xiang==3)ans=solve2(0,-1);
if(xiang==4)ans=solve2(1,-1);
}
else{
if(xiang==1)ans=solve3(1,0);
if(xiang==2)ans=solve3(0,0);
if(xiang==3)ans=solve3(0,-1);
if(xiang==4)ans=solve3(1,-1);
}
printf("%lld\n",ans);
}
return 0;
}