自由树(即无环连通图)T=(V,E)的直径是树中所有顶点之间最短路径的最大值。试设计一个时间复杂度尽可能低的算法求T的直径。
typedef struct graph
{
int edges[maxsize][maxsize];
int vex[maxsize];
int n;
}*graph;
void Floyd(graph g,int path[][maxsize],int dist[][maxsize])
{
int i,j,k;
for(i=0;i<g->n;i++) //初始化
for(j=0;j<g->n;j++)
{
dist[i][j]=g->edges[i][j];
path[i][j]=-1;
}
for(k=0;k<g->n;k++) //选择一个顶点k进行更新
for(i=0;i<g->n;i++)
for(j=0;j<g->n;j++)
if(dist[i][j]>dist[i][k]+dist[k][j])
{
dist[i][j]=dist[i][k]+dist[k][j];
path[i][j]=k;
}
}
int Fun(graph g)
{
int dist[maxsize][maxsize],path[maxsize][maxsize];
Floyd(g,path,dist);
int i,j,max=0;
for(i=0;i<g->n;i++)
for(j=0;j<g->n;j++)
if(dist[i][j]>max)
max=dist[i][j];
return max;
}
百钱买百鸡问题:鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一;百钱买百鸡,则翁、母、雏各几何?
思路:暴力枚举。
如果用数学的方法解决百钱买百鸡问题,可将该问题抽象成方程式组。设公鸡 x 只,母鸡 y 只,小鸡 z 只,得到以下方程式组:
A:5x+3y+1/3z = 100
B:x+y+z = 100
C:0 <= x <= 100
D:0 <= y <= 100
E:0 <= z <= 100
void main()
{
int jw,jm,jc;
for(jw=0;jw<=100;jw++)
for(jm=0;jm<=100;jm++)
for(jc=0;jc<=100;jc++)
if(5*jw+3*jm+jc/3==100&&jc%3==0&&jw+jm+jc==100)
printf("鸡翁%d个,鸡母%d个,鸡雏%d个\n",jw,jm,jc);
}
用不完全相同的四个数字组成一个四位数,然后将组成这个四位数的四个数字重新排序,组成一个最大的数和一个最小的数,并用最大的数减去最小的数,对减得的差再重复上述操作,差不够四位数时,用零补位。不断地做下去,最后变成了一个固定不变的数:6174。卡布列卡做了大量的试验,结果不论从任何满足条件的四位数开始,最后总能变成6174。因此,卡布列卡风趣地把6174叫做卡布列卡常数。
例如,从4231开始,把4231重新排列成4321和1234,两数相减得3087;再把3087重新排列成8730和0378,两数相减得8352;再把8352重新排列成8532和2358,相减得6174;再把6174重新排列成7641和1467,两数相减仍然得6174。编写程序,输入一个四位数,验证猜想。
void sort(int a[],int n)//升序,冒泡排序
{
int i,j;
for(i=0;i<n-1;i++)
for(j=0;j<n-1-i;j++)
if(a[j]>a[j+1])
{
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
void main()
{
int n;
scanf("%d",&n);
int a[4],max,min;
while(n!=6174)
{
int k=0;
for(int i=0;i<4;i++)//取各位数字
{
a[k++]=n%10;
n=n/10;
}
sort(a,4);//数字排序
int max=0,min=0;
for(int i=0;i<4;i++)//求最大和最小数
{
max=max*10+a[3-i];
min=min*10+a[i];
}
n=max-min;
printf("%d减%d等于%d\n",max,min,n);
}
}