ZCMU—1545

1545: 完美变换

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 35   Solved: 13
[ Submit][ Status][ Web Board]

Description

给你一个数n,每次只能进行减1 或者加2的操作,如果n能整除3,可以进行除3的操作,能用最少的次数把n进行以上操作后变为1的操作称为n的一个最小变换,比如7->9->3->1,7->6->2->1 都是n的最小变换,最小变换次数为3,在最小变换中,字典序最小的序列称为完美变换序列。求n的最小变换次数和完美变换序列

Input

输入多组数据,每行输入一个整数n (2<=n<=10^9)

Output

对于每个n,输出最小变换次数,输出一个空格,再输出完美变换序列,序列中每两个数之间用 -> 连接。

Sample Input

7

Sample Output

3 7->6->2->1

【分析】

乍一看以为是个什么高端数论.....n有点大,但是想一想可以发现其实可以搜啊....对当前now有三个操作/3,-1,+2,但是dfs显然会超时,所以改成bfs...结果就过了....
就是输出稍微有一点麻烦,不过也还好...bfs过程中用一个father数组记录路径,然后递归倒过来输出就可以了。
因为这里的n比较大所以vis标记需要用map,数组开不下的...另外这里我一开始以为不需要清空vis和father,因为我下意识的以为可以重复利用...MLE一次之后就发现自己太蠢了...大概半夜做题目脑子蠢蠢的hhh
【代码】
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;

map<int,int>father;
map<int,bool>vis;

void write(int x)
{
	if (father[x]==x)
		printf("%d",x);
	else
	{
		write(father[x]);
		printf("->%d",x);
	}
} 

void bfs(int n)
{
	vis.clear();
	father.clear();
	queue<pair<int,int> >q;
	q.push(make_pair(n,0));
	vis[n]=1;
	father[n]=n;
	int now,noww;
	while (!q.empty())
	{
		now=q.front().first;
		noww=q.front().second;
		if (now==1)
		{
			printf("%d ",noww);
			write(1);
			puts("");
			return ;
		} 
		q.pop();
		if (now%3==0&&!vis[now/3])
		{
			q.push(make_pair(now/3,noww+1));
			father[now/3]=now;
			vis[now/3]=1;
		}
		if (!vis[now-1])
		{
			q.push(make_pair(now-1,noww+1));
			father[now-1]=now;
			vis[now-1]=1;
		}
		if (!vis[now+2])
		{
			q.push(make_pair(now+2,noww+1));
			father[now+2]=now;
			vis[now+2]=1;
		}
	}
}

int main()
{
	int n;
	while (~scanf("%d",&n)) bfs(n);
	return 0;
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值