发现竟然读不懂题。努力静下来,再读题,总算有了眉目。
4→3→1→7
4的约数,不包括本身,1,2,约数和是1+2=3,
3的约数,不包括本身,1,约数和是1
7的约数,不包括本身,1,约数和是1
故可这样变换7->1->3->4
还是有些晕,还是要再找找其他可能变换途径。
进一步思考样例,找出7以内所有符合条件的数据
数值 约数和 符合题意 打上序号
1 1 否
2 1 是 1
3 1 是 2
4 1+2=3 是 3
5 1 是 4
6 1+2+3=6 否
7 1 是 5
选出符合题意的数,拼接在一起,发现是一棵树
进一步研究,发现最多变换步数是找这个树的最长链(红色部分)
该题的基本思路有了:
找出n范围内所有符合题意的数据及约束和。
将符合题意的数据拼接成树。
找出树的最长链(完全是笔者对立的思路:考虑从根节点开始,找出最大深度对应的点,再以该对应点为根节点,继续寻找最大深度,这次的最大深度,就是最长链的长度)。
该题,还需特判:
n==1时,输出0
在提交代码前,测试了几组数据
n==1输出0
n==2输出1
n==3输出2
n==4输出3
n==5输出3
n==6输出3
n==7输出3
发现没有问题,提交AC,代码如下:
ybt
通过
测试点 | 结果 | 内存 | 时间 |
测试点1 | 答案正确 | 616KB | 2MS |
测试点2 | 答案正确 | 628KB | 3MS |
测试点3 | 答案正确 | 620KB | 3MS |
测试点4 | 答案正确 | 624KB | 2MS |
测试点5 | 答案正确 | 640KB | 2MS |
测试点6 | 答案正确 | 800KB | 3MS |
测试点7 | 答案正确 | 848KB | 4MS |
测试点8 | 答案正确 | 1084KB | 8MS |
测试点9 | 答案正确 | 1596KB | 20MS |
测试点10 | 答案正确 | 1776KB | 26MS |
LOJ
#include <bits/stdc++.h>
#define maxn 50010
using namespace std;
struct node{
int to,next;
}e[maxn<<1];
int head[maxn],tot,n,dep[maxn],mx,k;//dep[]记录深度(即离根的距离)
void add(int u,int v){
tot++,e[tot].to=v,e[tot].next=head[u],head[u]=tot;
}
void init(){
int x,y,z;
scanf("%d",&n);
for(x=2;x<=n;x++){
y=1;
for(z=2;z*z<=x;z++)
if(x%z==0){
y+=z;
if(x/z!=z)
y+=x/z;
}
if(y<x){
add(x,y),add(y,x);//无向图
}
}
}
void dfs(int u,int fa){
int i,v;
for(i=head[u];i;i=e[i].next){
v=e[i].to;
if(v==fa)continue;
dep[v]=dep[u]+1;
if(dep[v]>mx)mx=dep[v],k=v;
dfs(v,u);
}
}
int main(){
init();
if(n==1){//特判
printf("0\n");
return 0;
}
dfs(1,-1);//第一遍找最大深度
dep[k]=0;
dfs(k,-1);//第二变找最大深度
printf("%d\n",mx);
return 0;
}
上述代码完全独立编写,没有参考任何资料。
该习得什么:
很关键的一点,建模,将数据连接成树.
约数计算.
树上最长链(两次找最大深度)