UOJ Logo xrlong的博客

博客

最少步数 O(1)算法详解

2022-06-11 20:10:47 By xrlong

最小步数(普及)

ireallyakioi首先发行, 现名GOD_HJ(第一次写博客,虽然很简单,但敬请斧正)

一般算法: BFS)

因为DFS回溯太满了,所以用BFS。 (思路度娘一搜就有,不在过多解释解释)。

code:

#include <bits/stdc++.h>
using namespace std;
int a[105][105];
int dx[]={-2,-2,-2,-2,-1,1,2,2,2,2,1,-1};
int dy[]={-2,-1,1,2,2,2,2,1,-1,-2,-2,-2};
int main(){
    for(int i=0;i<100;i++)
        for(int j=0;j<100;j++) 
            a[i][j]=-1;
    a[0][0]=0;
    int x1,y1,x2,y2;
    scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
    queue<int> x,y,bs;
    x.push(0);
    y.push(0);
    bs.push(0);
    while(!(x.empty()&&y.empty())){
        for(int i=0;i<12;i++){
            int xx=x.front(),xy=y.front(),bss=bs.front()+1;
               xx+=dx[i];
            xy+=dy[i];
            if(xx<0||xx>99||xy<0||xy>99) continue;
            if(a[xx][xy]==-1){
            }
        }
        x.pop();
        y.pop();
        bs.pop();
    }
    printf("%d\n%d",a[x1-1][y1-1],a[x2-1][y2-1]);
}

O(1)算法:算数(朴实无华)

这里只讨论第一次输入,第二次同第一次。

设输入为$x,y$,则$(1,1) (1,y) (x,y) (x,1)$为一个矩形(矩形的长,宽是长度(坐标-1),不是坐标)

那么,$最小步数=ceil(长~~(长的一条边是长)~~÷2)$,理由如下:

为了方便描述,把所有长方形“立起来”。

如果比较:(如图)。

图挂了(就是按照下面的方法可以跳到,长是2的倍数)

那么就可以一直以田字跳,直到到达了边界,在“左右左右”跳;

所以 $最小步数=长÷2$

那如果不巧:(如图)。

图挂了(就是按照上面的方法跳不到,长不是2的倍数)

那么就在开始时先向有一下,在跳田字,“左右左右”……(如图)。

咳咳,自己想吧

这个图同时也证明了,当长不整除4时的画法。

此时, $最小步数=ceil(长÷2)$

如果宽是奇数,那就先走一个“日”在走“田”(相当于把奇数减一化成偶数),不会影响结果(感谢pink_rabbit提醒)。

但是!!

可以发现,当 $长 \le 2$ 时,方法并不适用,所以,需要特判

code 见下(建议自我思索一下)……

·

·

·

·

·

·

code

#include<bits/stdc++.h> 
using namespace std;
int main(){
    for(int i=0;i<2;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        int wlong = max(x-1,y-1);//长
        if(wlong<=1){//特判
            if(x==2&&y==2) printf("%d\n",3);
            else printf("%d\n",2);
            continue;
        }else if(wlong==2){
            printf("%d\n",1);
            continue;
        }
        printf("%d\n",int(wlong/2.0+0.5));//输出
    }
}

吊打集训队不是我说的。

评论

GOD_HJ
%%%
GOD_HJ
@xrlong 不是完全的O(1),但相差不多! %%%
xrlong
朴实无华
pink_rabbit
宽是奇数的情况呢?
yechengjun_2027
%%%

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。