问题描述
有一个整数 n,每一次,可以将这个数加 1 、减 1 或除以 2,其中除以 2 必须在数是偶数的时候才允许。
例如,2021 经过一次操作可以变成 2020、2022。
再如,2022 经过一次操作可以变成 2021、2023 或 1011。
请问,n最少经过多少次操作可以变成 1。
思路:
用数字作为结点,三种变换规则做边,来建立图,然后用BFS求从2021到1的最短路径。所以题干的设问“最少经过多少次操作”转变为最短路径问题。
答案:14
AC代码:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Main
{
static PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
static int N = (int)3000 + 10;
static Queue<Integer> q = new LinkedList<>();
static boolean visited[] = new boolean[N];
static int dist[] = new int[N]; // 存i节点距离2021的操作次数
static int bfs(int n)
{
q.add(n);
visited[n] = true;
dist[n] = 0;
while(!q.isEmpty())
{
int t = q.poll();
if(t == 1) break;
if(!visited[t + 1])
{
visited[t + 1] = true;
dist[t + 1] = dist[t] + 1;
q.add(t + 1);
}
if(!visited[t - 1])
{
visited[t - 1] = true;
dist[t - 1] = dist[t] + 1;
q.add(t - 1);
}
if(t % 2 == 0 && !visited[t / 2])
{
visited[t / 2] = true;
dist[t / 2] = dist[t] + 1;
q.add(t / 2);
}
}
return dist[1];
}
public static void main(String[] args ) throws IOException, ParseException
{
int n = 2021;
pw.println(bfs(n));
pw.flush();
}
}
class rd
{
static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer tokenizer = new StringTokenizer("");
static String nextLine() throws IOException { return reader.readLine(); }
static String next() throws IOException
{
while (!tokenizer.hasMoreTokens()) tokenizer = new StringTokenizer(reader.readLine());
return tokenizer.nextToken();
}
static int nextInt() throws IOException { return Integer.parseInt(next()); }
static double nextDouble() throws IOException { return Double.parseDouble(next()); }
static long nextLong() throws IOException { return Long.parseLong(next());}
static BigInteger nextBigInteger() throws IOException { return new BigInteger(rd.nextLine()); }
}
class PII
{
int x,y;
public PII(int x ,int y)
{
this.x = x;
this.y = y;
}
}