001 : //========================================
002 : // program.c --- ACM ICPC 2012 Domestic B
003 : //  Created by M.Miyazaki [2013.01.13]
004 : //========================================
005 : 
006 : #include <stdio.h>
007 : #include <stdlib.h>
008 : #include <string.h>
009 : 
010 : /**
011 :  * 数値リストの最大要素数
012 :  */
013 : #define MAXELMS 21
014 : 
015 : /**
016 :  * 最大桁数
017 :  */
018 : #define MAXLEN 6
019 : 
020 : /*
021 :  * 関数のプロトタイプ宣言
022 :  */
023 : int main(int argc, char * argv[]);
024 : int input(int * f, int * s);
025 : void pfrm(int n, int d);
026 : int getMax(int n, int d);
027 : int getMin(int n, int d);
028 : void val2str(char str[], int val, int len);
029 : int getIndex(int ary[], int maxi);
030 : 
031 : /**
032 :  * メインプログラム.
033 :  *
034 :  * @param argc 引数の数
035 :  * @param argv[] 引数の値
036 :  * @return 終了時の値(正常終了ならEXIT_SUCCESS)
037 :  */
038 : int main(int argc, char * argv[])
039 : {
040 :     int n;   // 入力された数値
041 :     int d;   // 数値および桁数
042 :     
043 :     while (input(&n, &d) == 1)
044 :     {
045 :         pfrm(n, d);
046 :     }
047 :     
048 :     return EXIT_SUCCESS;
049 : }
050 : 
051 : /**
052 :  * 2数の入力を担う関数.
053 :  *
054 :  * @param f 1つ目の値を格納するためのポインタ
055 :  * @param s 2つ目の値を格納するためのポインタ
056 :  * @return 「0 0」が入力された場合は0、それ以外は1を応答する。
057 :  */
058 : int input(int * f, int * s)
059 : {
060 :     int r = 1;
061 :     
062 :     scanf("%d %d", f, s);
063 :     
064 :     if (*f == 0  &&  *s == 0)
065 :     {
066 :         r = 0;
067 :     }
068 : 
069 :     return r;
070 : }
071 : 
072 : /**
073 :  * 数値と桁数から、問題の趣旨に沿った文字列を出力する関数.
074 :  *
075 :  * @param n 入力値(処理対象となる数値)
076 :  * @param d 指定桁数
077 :  */
078 : void pfrm(int n, int d)
079 : {
080 :     int ary[MAXELMS];   // 数値リスト
081 :     int c = 0;          // 数値リスト用のカウンタ
082 :     int max, min;       // 桁の入れ替えから求まる最大値と最小値
083 :     int i;          // 重複要素のインデックス
084 :     
085 :     for (c = 0; c < MAXELMS; c++)
086 :     {
087 :         ary[c] = -1;
088 :     }
089 :     c = 0;
090 :     ary[c] = n;
091 :     
092 :     while (1)
093 :     {
094 :         max = getMax(n, d);
095 :         min = getMin(n, d);
096 :         
097 :         n = max - min;
098 :         c++;
099 :         ary[c] = n;
100 :         i = getIndex(ary, c);
101 :         
102 :         if (i != -1)
103 :         {
104 :             printf("%d ", i);
105 :             printf("%d ", ary[i]);
106 :             printf("%d\n", c - i);
107 :             break;
108 :         }
109 :     }
110 :     
111 :     return;
112 : }
113 : 
114 : /**
115 :  * 入力値の各桁を入れ替えて最大値を応答する.
116 :  *
117 :  * @param n 入力値(処理対象となる数値)
118 :  * @param d 指定桁数
119 :  * @return 最大値
120 :  */
121 : int getMax(int n, int d)
122 : {
123 :     int max;
124 :     int i;
125 :     char str[MAXLEN + 1];
126 :     
127 :     val2str(str, n, d);
128 :     
129 :     for (i = 0; i < strlen(str) - 1; i++)
130 :     {
131 :         if (str[i] < str[i + 1])
132 :         {
133 :             char tmp;
134 :             tmp        = str[i];
135 :             str[i]     = str[i + 1];
136 :             str[i + 1] = tmp;
137 :             i = -1;
138 :         }
139 :     }
140 :     
141 :     max = atoi(str);
142 :     
143 :     return max;
144 : }
145 : 
146 : /**
147 :  * 入力値の各桁を入れ替えて最小値を応答する.
148 :  *
149 :  * @param n 入力値(処理対象となる数値)
150 :  * @param d 指定桁数
151 :  * @return 最小値
152 :  */
153 : int getMin(int n, int d)
154 : {
155 :     int min;
156 :     int i;
157 :     char str[MAXLEN + 1];
158 :     
159 :     val2str(str, n, d);
160 :     
161 :     for (i = 0; i < strlen(str) - 1; i++)
162 :     {
163 :         if (str[i] > str[i + 1])
164 :         {
165 :             char tmp;
166 :             tmp        = str[i];
167 :             str[i]     = str[i + 1];
168 :             str[i + 1] = tmp;
169 :             i = -1;
170 :         }
171 :     }
172 :     
173 :     min = atoi(str);
174 :     
175 :     return min;
176 : }
177 : 
178 : /**
179 :  * 数値から文字列に変換して応答する。ただし、指定桁数に届かない分は先頭を0で埋める。
180 :  *
181 :  * @param str[] 変換後の文字列を格納する配列
182 :  * @param val 変換元の数値
183 :  * @param len 指定桁数
184 :  */
185 : void val2str(char str[], int val, int len)
186 : {
187 :     char fstr[10];
188 :     
189 :     sprintf(fstr, "%%0%dd", len);
190 :     sprintf(str, fstr, val);
191 :     
192 :     return;
193 : }
194 : 
195 : /**
196 :  * 配列中に重複要素があった場合、その要素が最初に出現するインデックスを応答する.
197 :  *
198 :  * @param ary[] 検査対象となる数値リスト
199 :  * @param maxi 数値リストに対して参照できる最大のインデックス
200 :  * @return 重複要素の格納場所を指すインデックス。重複要素がなければ-1を応答する。
201 :  */
202 : int getIndex(int ary[], int maxi)
203 : {
204 :     int val = -1;
205 :     int i1, i2;   // 注目している2要素を指すインデックス
206 :     
207 :     for (i1 = 0; i1 < maxi; i1++)
208 :     {
209 :         for (i2 = i1 + 1; i2 <= maxi; i2++)
210 :         {
211 :             if (ary[i1] == ary[i2])
212 :             {
213 :                 // 重複要素が見つかったため、ループから脱出する。
214 :                 val = i1;
215 :                 i1 = MAXELMS;
216 :                 i2 = MAXELMS;
217 :             }
218 :         }
219 :     }
220 :     
221 :     return val;
222 : }
223 : 

This document was generated by NanigashiBiyori on 2013/01/14 at 00:17:21.