题目链接:https://www.nowcoder.com/acm/contest/106/J

题意就是给你两个数a,b,然后a每次可以加1减1或者加f(x)减f(x),f(x)的值就是x的二进制的1的个数,问a最少需要变换多少次才能变成b。直接用bfs就能做了,二进制的话用bitset会方便一点,剩下就看代码吧。


AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <bitset>
using namespace std;
struct Node
{
  int x,step;
}S,E,Now,Next;
int vis[1000005];

int fun(int x)
{
  int ans = 0;
  bitset<20> b(x);
  string str = b.to_string();
  int len = str.length();
  for(int i=0;i<len;i++)
  {
    if(str[i]=='1')ans++;
  }
  return ans;
}

int bfs(){
  memset(vis,0,sizeof(vis));
  S.step = 0;
  queue<Node> q;
  q.push(S);
  while(!q.empty())
  {
    Now = q.front();
    q.pop();
    if(Now.x == E.x)
    {
      return Now.step;
    }
    for(int i=0;i<4;i++)
    {
      if(i==0)Next.x=Now.x+1;
      if(i==1)Next.x=Now.x-1;
      if(i==2)Next.x=fun(Now.x) + Now.x;
      if(i==3)Next.x=Now.x - fun(Now.x);
      if(Next.x>=0 && Next.x <= 1000000 && vis[Next.x]==0){
        vis[Next.x] = 1;
        Next.step = Now.step + 1;
        q.push(Next);
      }
    }
  }
    return 0;
}

int main()
{
  scanf("%d%d",&S.x,&E.x);
  int temp = bfs();
  printf("%d\n",temp);
  return 0;
}