1. 程式人生 > >【紫書】例題3-5 生成元(Digit Generator, ACM/ICPC Seoul 2005, UVa1583)

【紫書】例題3-5 生成元(Digit Generator, ACM/ICPC Seoul 2005, UVa1583)

暴力 真的 mes sed stream 簡單 post flag 個數

【題目描述】

如果x加上x的各個數字之和得到y,就說x是y的生成元。給出n(1≤n≤100000),求最小生成元。無解輸出0。例如,n=216,121,2005時的解分別為198,0,1979。

【代碼實現】


  方法1

 1 #include <iostream>
 2 #include <cstdio>
 3 
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     int n = 0;
 9     while ( scanf ("%d", &n) == 1) {
10         int flag = 1;
11         for
( int i = 1; i <= n; i++ ) { 12 int t = i, sum = 0; 13 while ( t > 0 ) { 14 sum += t % 10; 15 t /= 10; 16 } 17 // printf ("i = %d, sum = %d\n", i, sum); 18 if ( i + sum == n ) { 19 printf ("%d\n
", i); 20 flag = 0; 21 break; 22 } 23 } 24 if ( flag ) printf ("0\n"); 25 } 26 27 // printf ("Time used = %f\n", (double)clock() / CLOCKS_PER_SEC); 28 29 return 0; 30 }

  方法2

 1 #include <stdio.h>
 2 #include <string
.h> 3 4 #define MAX (int)1e5 + 10 5 6 using namespace std; 7 8 int a[MAX]; 9 10 int main() 11 { 12 for ( int i = 1; i < MAX; i++ ) { 13 int t = i, j = i; 14 while ( t ) { 15 j += t % 10; 16 t /= 10; 17 } 18 if ( a[j] == 0 || a[j] > i ) a[j] = i; 19 } 20 21 int n = 0; 22 while ( scanf ("%d", &n) == 1 ) printf ("%d\n", a[n]); 23 24 return 0; 25 }

【總結】

自己的方法是純暴力枚舉,真的簡單。。但對一個數進行按位拆分的時候寫的麻煩了。。明明很久以前就寫過的OTL。

作者的方法是,先用一個數組將所有下標對應的最小生成元都存起來,最後輸入只要查表即可。比單純的暴力枚舉要高效很多,不必每次輸入n都從1~n-1找一遍。妙啊,巧用數組!

【紫書】例題3-5 生成元(Digit Generator, ACM/ICPC Seoul 2005, UVa1583)