0
点赞
收藏
分享

微信扫一扫

ZCMU—1545

夏沐沐 2022-09-07 阅读 348


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;
}



举报

相关推荐

ZCMU—A

ZCMU—1710

ZCMU—1778

ZCMU 1657

ZCMU—C

ZCMU—1019

ZCMU—1207

ZCMU—1779

0 条评论