题意
从昏迷中醒来,小明发现自己被关在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;
}