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;	
}
posted @ 2019-10-20 20:01  lihan123  阅读(131)  评论(0编辑  收藏  举报