Problem G
数字河
时限:1000ms 内存限制:10000K 总时限:3000ms
描述:
数字河中的一个数n 的后继数是n 加上其每位数字的和。例如,12345的后继数是12360,因为12345+1+2+3+4+5=12360。如果数字河的第一个数为k,我们就称此数字河为river k。例如,river 480 代表序列{480, 492, 507, 519, ...},river 483 代表序列{483, 498, 519, ...}。
当两个数字河有相同的元素时,我们称这两个数字河在此元素处相遇。例如,river 480 和river 483 在元素519处相遇。所有数字河都会和river 1, river 3 或river 9 相遇。编程计算给定的数字河最先与以上三条河流中的哪一条相遇,在何元素处相遇?
输入:
输入文件包括多组测试用例,每个测试用例占一行,以“0”标志文件结束,该行无需处理。
每行给定一个整数 n ,(1<=n<=16384) ,即river n。
输出:
对于每个测试用例输出两行,第一行为测试用例号,第二行输出“first meets river x at y”。其中,y表示river n 最先遇到的river x中的最小元素值(x = 1,3,9)。
输入样例:
117 52 0
输出样例:
Case #1 first meets river 9 at 117 Case #2
first meets river 1 at 107
#include<stdio.h> #include<stdlib.h> #define MAX_TIMES 1200 int *river(int i, int* a); void meet(int n, int i, int j, int k); int main() { int n, m = 1, i = 1, j = 3, k = 9; while (1) // for (n = 1; n < 100; n++)// 可用此循环依次检验整数 { scanf("%d", &n); if (0 == n) break; printf("Case #%d\n", m); m++; meet(n, i, j, k); } return 0; } int *river(int i, int* a)//数字河函数 { for (int j = 0; j <= MAX_TIMES; j++) { a[j] = i; i = i + i % 10 + i / 10 % 10 + i / 100 % 10 + i / 1000 % 10 + i / 10000 % 10; } return a; } void meet(int n, int i, int j, int k) {//数组的动态内存分配 int *A = (int*)malloc(MAX_TIMES * sizeof(int)); int *B = (int*)malloc(MAX_TIMES * sizeof(int)); int *C = (int*)malloc(MAX_TIMES * sizeof(int)); int *D = (int*)malloc(MAX_TIMES * sizeof(int)); int num = 0; int a1, b1, c1, d1; for (int a = 0; a <= MAX_TIMES; a++) { for (int b = 0; b <= MAX_TIMES; b++) { a1 = river(n, A)[a]; b1 = river(i, B)[b]; c1 = river(j, C)[b]; d1 = river(k, D)[b]; while (a1 > b1 && a1 > c1 && a1 > d1) { b++; b1 = river(i, B)[b]; c1 = river(j, C)[b]; d1 = river(k, D)[b]; }//并列的三个if可节省运算时间 if (a1 == b1) { num = a1; printf("first meets river %d at %d\n", i, num); break; } if (a1 == c1) { num = a1; printf("first meets river %d at %d\n", j, num); break; } if (a1 == d1) { num = a1; printf("first meets river %d at %d\n", k, num); break; } while (a1 < b1 && a1 < c1 && a1 < d1)//此时数字河不能相遇 break; } if (num) break; } }