第七届蓝桥杯国赛 一步之遥

24 篇文章 0 订阅
12 篇文章 0 订阅

题意

从昏迷中醒来,小明发现自己被关在X星球的废矿车里。
矿车停在平直的废弃的轨道上。
他的面前是两个按钮,分别写着“F”和“B”。

小明突然记起来,这两个按钮可以控制矿车在轨道上前进和后退。
按F,会前进97米。按B会后退127米。
透过昏暗的灯光,小明看到自己前方1米远正好有个监控探头。
他必须设法使得矿车正好停在摄像头的下方,才有机会争取同伴的援助。
或许,通过多次操作F和B可以办到。

矿车上的动力已经不太足,黄色的警示灯在默默闪烁...
每次进行 F 或 B 操作都会消耗一定的能量。
小明飞快地计算,至少要多少次操作,才能把矿车准确地停在前方1米远的地方。

请填写为了达成目标,最少需要操作的次数。

注意,需要提交的是一个整数,不要填写任何无关内容(比如:解释说明等)

解题思路

现在觉得做好的解法是用扩展欧几里得,因为97,127互质。两组特解之和即为答案
暴力枚举交一发,开始还搜索交一发…………

代码实现

扩展欧几里得
#include <iostream>
#include<cstdio>
using namespace std;
#define ll __int64
int d;
int ex_gcd(int a,int b,int &x,int &y)
{
    if(!b)
    {
        d=a,x=1,y=0;
    }
    else
    {
        ex_gcd(b,a%b,y,x);
        y-=(a/b)*x;
    }
    return d;
}
int main()
{
    int x,y;
    ex_gcd(-127,97,x,y);
    printf("%d\n",x+y);
}
枚举
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int main()
{
    int x,y;
    for(int x=0;x<100;x++)
    {
        for(int y=0;y<100;y++)
        {
            if(97*x-127*y==1)
            {
                printf("%d %d %d\n",x,y,x+y);
            }
        }
    }
}
搜索
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#include<queue>
#define maxn 100000
queue<int>qu;
int visit[maxn][2];   //0代表正数,1代表是负数
int dir[2]= {97,-127};
int step[maxn][2];
void BFS()
{
    qu.push(0);
    visit[0][0]=visit[0][1]=1;
    while(!qu.empty())
    {
        int t=qu.front();
        qu.pop();
        if(t==1)
        {
            printf("%d\n",step[t][0]);
            break;
        }
        for(int i=0; i<2; i++)
        {
            int nt=t+dir[i];
            if(nt>0)
            {
                if(!visit[nt][0])
                {
                    qu.push(nt);
                    visit[nt][0]=1;
                    if(t>0)
                        step[nt][0]=step[t][0]+1;
                    else
                        step[nt][0]=step[-t][1]+1;
                }
            }
             if(nt<0)
            {
                if(!visit[-nt][1])
                {
                    qu.push(nt);
                    visit[-nt][1]=1;
                    if(t>0)
                        step[-nt][0]=step[t][0]+1;
                    else
                        step[-nt][0]=step[-t][1]+1;
                }
            }
        }
    }
}
int main()
{
    memset(visit,0,sizeof(visit));
    memset(step,0,sizeof(step));
    BFS();
    return 0;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值