这道题可以用类似H数(Humble Number)的方法做。
用一个结构体数组f[1..n]记录1的倍数、2的倍数、3的倍数、……n的倍数。
初始时,全部都是1倍。如,N=5,M=5时,
i | 1 | 2 | 3 | 4 | 5 |
f[i].num | 1 | 2 | 3 | 4 | 5 |
f[i].cnt | 1 | 1 | 1 | 1 | 1 |
f[i].multi | 1 | 2 | 3 | 4 | 5 |
再将它们按multi从小到大排序,取出最小的一个或几个,计数。
之后,被取出的结构体cnt加一,变成:
i | 1 | 2 | 3 | 4 | 5 |
F[i].num | 1 | 2 | 3 | 4 | 5 |
F[i].cnt | 2 | 1 | 1 | 1 | 1 |
F[i].multi | 2 | 2 | 3 | 4 | 5 |
再取出两个2:
i | 1 | 2 | 3 | 4 | 5 |
F[i].num | 1 | 2 | 3 | 4 | 5 |
F[i].cnt | 3 | 2 | 1 | 1 | 1 |
F[i].multi | 3 | 4 | 3 | 4 | 5 |
排序:
i | 1 | 2 | 3 | 4 | 5 |
F[i].num | 1 | 3 | 2 | 4 | 5 |
F[i].cnt | 3 | 1 | 2 | 1 | 1 |
F[i].multi | 3 | 3 | 3 | 4 | 5 |
以此类推。
运用QSORT可以大大加快排序速度。
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
struct p{
long long cnt,num,multi;
}f[500002];
int cmp(const void *a,const void *b){
long long k;
k=(*(p *)a).multi-(*(p *)b).multi;
if(k>0)return 1;
if(k==0)return 0;
if(k<0)return -1;
}
int main(){
long long i,temp,j,I;
long long k;
long long n,m;
scanf("%I64d %I64d %I64d",&n,&m,&k);
if(n>m){
temp=n;n=m;m=temp;
}
memset(f,0,sizeof(f));
for(i=0;i<n;i++){
f[i].cnt=1;
f[i].num=i+1;
f[i].multi=(i+1);
}
i=j=0;
while(j<k){
printf("I=%d, J=%d\n",i,j);
qsort(f,n,sizeof(f[0]),cmp);
temp=f[0].multi;
f[0].cnt++;
f[0].multi=f[0].cnt*f[0].num;
j++;
i=1;
while(f[i].multi==temp){
f[i].cnt++;
f[i].multi=f[i].cnt*f[i].num;
i++;j++;
}
}
printf("%I64d",f[i-1].multi-f[i-1].num);
return 0;
}