一本通1577【例 3】数字转换
1577:【例 3】数字转换
时间限制: 1000 ms 内存限制: 524288 KB
题目描述
如果一个数 x 的约数和 y (不包括他本身)比他本身小,那么 x 可以变成 y,y 也可以变成 x。例如 4 可以变为 3,1 可以变为 7。限定所有数字变换在不超过 n 的正整数范围内进行,求不断进行数字变换且不出现重复数字的最多变换步数。
输入格式
输入一个正整数 n。
输出格式
输出不断进行数字变换且不出现重复数字的最多变换步数。
样例
样例输入
7
样例输出
3
样例说明
一种方案为 4→3→1→7。
数据范围与提示
对于 100% 的数据,1≤n≤50000。
sol:因为都是由大数向小数连边(虽然无向边但是建图的时候是由大向小产生的),所以一定无环,看成一棵树,找到最长链就可以了,又因为是变换次数(边数),所以减1
附上样例7的图
#include <bits/stdc++.h> using namespace std; inline int read() { int s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(int x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } inline void writeln(int x) { write(x); putchar('\n'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) writeln(x) const int N=50005,M=100005; int n; struct Tree { int tot,Next[M],to[M],head[N]; inline void add(int x,int y) { Next[++tot]=head[x]; to[tot]=y; head[x]=tot; return; } int dp[N],ans; inline void dfs(int x,int fa) { dp[x]=1; int i; for(i=head[x];i;i=Next[i]) if(to[i]!=fa) { dfs(to[i],x); ans=max(ans,dp[x]+dp[to[i]]); dp[x]=max(dp[x],dp[to[i]]+1); } } inline void Solve() { dfs(1,0); Wl(ans-1); return; } inline void Init() { tot=0; memset(head,0,sizeof head); ans=0; return; } }T; int main() { int i,j; T.Init(); R(n); for(i=2;i<=n;i++) { int sum=0; for(j=1;j<=sqrt(i);j++) if(i%j==0) { sum+=j; if((j!=1)&&(j*j!=i)) sum+=i/j; } if(sum>=i) continue; T.add(i,sum); T.add(sum,i); } T.Solve(); return 0; }
河田は河田、赤木は赤木……。
私は誰ですか。教えてください、私は誰ですか。
そうだ、俺はあきらめない男、三井寿だ!