T51485 键盘(spfa)

满分做法:

本题直接搜索即可,因为要记录最优值,直接spfa就好了。

#include<bits/stdc++.h>
using namespace std;
const int maxm=1e6+7;
int n,m;
int dis[maxm];
bool vis[maxm];
queue<int > q;
void spfa()
{
 if(m<=n)
 {
   dis[m]=0;
   vis[m]=1;
   q.push(m);
 }
 else
 {
   dis[0]=3;
   dis[n]=m-n;//直接删除 
   vis[0]=1;
   q.push(0);   
 }
 while(q.size())
 {
   int x=q.front();
   q.pop();
   vis[x]=0;
   if(x<n&&dis[x+1]>dis[x]+1)
   {
     dis[x+1]=dis[x]+1;
     if(!vis[x+1])
     {
       vis[x+1]=1;
       q.push(x+1); 
     }
   }
   if(x>0&&dis[x-1]>dis[x]+1)
   {
     dis[x-1]=dis[x]+1;
     if(!vis[x-1])
     {
      vis[x-1]=1;
      q.push(x-1);  
     }
   }
   if(x>0)//有字符才复制 
   {
    for(int i=2;x*(i-1)<=n;i++)
    {
     if(x*i>n&&dis[n]>dis[x]+2*(i+1)+x*i-n)//2*(i+1)为全选,复制,粘贴i-1次的总时间
     {
        dis[n]=dis[x]+2*(i+1)+x*i-n;
        if(!vis[n])
        {
         vis[n]=1;
         q.push(n); 
        }
     }
     if(x*i<=n&&dis[x*i]>dis[x]+2*(i+1))
     {
        dis[x*i]=dis[x]+2*(i+1);
        if(!vis[x*i])
        {
         vis[x*i]=1;
         q.push(x*i);   
        }   
     }
    }
   }
 }
}
int main()
{
 scanf("%d%d",&m,&n);
 memset(dis,63,sizeof(dis));
 spfa();
 printf("%d\n",dis[n]);
 return 0;  
}

猜你喜欢

转载自www.cnblogs.com/lihan123/p/11708864.html