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 MAX_ELEMENTS 21 014 : 015 : /** 016 : * 最大桁数 017 : */ 018 : #define MAX_LENGTH 6 019 : 020 : /* 021 : * 関数のプロトタイプ宣言 022 : */ 023 : int main(int argumentCount, char * argumentValues[]); 024 : int input(int * firstPointer, int * secondPointer); 025 : void perform(int aValue, int numberOfDigit); 026 : int getMaxNumber(int aValue, int numberOfDigit); 027 : int getMinNumber(int aValue, int numberOfDigit); 028 : void stringFromValueWithLength(char valueString[], int aValue, int length); 029 : int getIndexOfDuplication(int valueArray[], int maxIndex); 030 : 031 : /** 032 : * メインプログラム. 033 : * 034 : * @param argumentCount 引数の数 035 : * @param argumentValues[] 引数の値 036 : * @return 終了時の値(正常終了ならEXIT_SUCCESS) 037 : */ 038 : int main(int argumentCount, char * argumentValues[]) 039 : { 040 : int aValue; // 入力された数値 041 : int numberOfDigit; // 数値および桁数 042 : 043 : while (input(&aValue, &numberOfDigit) == 1) 044 : { 045 : perform(aValue, numberOfDigit); 046 : } 047 : 048 : return EXIT_SUCCESS; 049 : } 050 : 051 : /** 052 : * 2数の入力を担う関数. 053 : * 054 : * @param firstPointer 1つ目の値を格納するためのポインタ 055 : * @param secondPointer 2つ目の値を格納するためのポインタ 056 : * @return 「0 0」が入力された場合は0、それ以外は1を応答する。 057 : */ 058 : int input(int * firstPointer, int * secondPointer) 059 : { 060 : int returnValue = 1; 061 : 062 : scanf("%d %d", firstPointer, secondPointer); 063 : 064 : if (*firstPointer == 0 && *secondPointer == 0) 065 : { 066 : returnValue = 0; 067 : } 068 : 069 : return returnValue; 070 : } 071 : 072 : /** 073 : * 数値と桁数から、問題の趣旨に沿った文字列を出力する関数. 074 : * 075 : * @param aValue 入力値(処理対象となる数値) 076 : * @param numberOfDigit 指定桁数 077 : */ 078 : void perform(int aValue, int numberOfDigit) 079 : { 080 : int valueArray[MAX_ELEMENTS]; // 数値リスト 081 : int count = 0; // 数値リスト用のカウンタ 082 : int maxNumber, minNumber; // 桁の入れ替えから求まる最大値と最小値 083 : int indexOfDuplication; // 重複要素のインデックス 084 : 085 : for (count = 0; count < MAX_ELEMENTS; count++) 086 : { 087 : valueArray[count] = -1; 088 : } 089 : count = 0; 090 : valueArray[count] = aValue; 091 : 092 : while (1) 093 : { 094 : maxNumber = getMaxNumber(aValue, numberOfDigit); 095 : minNumber = getMinNumber(aValue, numberOfDigit); 096 : 097 : aValue = maxNumber - minNumber; 098 : count++; 099 : valueArray[count] = aValue; 100 : indexOfDuplication = getIndexOfDuplication(valueArray, count); 101 : 102 : if (indexOfDuplication != -1) 103 : { 104 : printf("%d ", indexOfDuplication); 105 : printf("%d ", valueArray[indexOfDuplication]); 106 : printf("%d\n", count - indexOfDuplication); 107 : break; 108 : } 109 : } 110 : 111 : return; 112 : } 113 : 114 : /** 115 : * 入力値の各桁を入れ替えて最大値を応答する. 116 : * 117 : * @param aValue 入力値(処理対象となる数値) 118 : * @param numberOfDigit 指定桁数 119 : * @return 最大値 120 : */ 121 : int getMaxNumber(int aValue, int numberOfDigit) 122 : { 123 : int maxNumber; 124 : int index; 125 : char valueString[MAX_LENGTH + 1]; 126 : 127 : stringFromValueWithLength(valueString, aValue, numberOfDigit); 128 : 129 : for (index = 0; index < strlen(valueString) - 1; index++) 130 : { 131 : if (valueString[index] < valueString[index + 1]) 132 : { 133 : char temporaryCharacter; 134 : temporaryCharacter = valueString[index]; 135 : valueString[index] = valueString[index + 1]; 136 : valueString[index + 1] = temporaryCharacter; 137 : index = -1; 138 : } 139 : } 140 : 141 : maxNumber = atoi(valueString); 142 : 143 : return maxNumber; 144 : } 145 : 146 : /** 147 : * 入力値の各桁を入れ替えて最小値を応答する. 148 : * 149 : * @param aValue 入力値(処理対象となる数値) 150 : * @param numberOfDigit 指定桁数 151 : * @return 最小値 152 : */ 153 : int getMinNumber(int aValue, int numberOfDigit) 154 : { 155 : int minNumber; 156 : int index; 157 : char valueString[MAX_LENGTH + 1]; 158 : 159 : stringFromValueWithLength(valueString, aValue, numberOfDigit); 160 : 161 : for (index = 0; index < strlen(valueString) - 1; index++) 162 : { 163 : if (valueString[index] > valueString[index + 1]) 164 : { 165 : char temporaryCharacter; 166 : temporaryCharacter = valueString[index]; 167 : valueString[index] = valueString[index + 1]; 168 : valueString[index + 1] = temporaryCharacter; 169 : index = -1; 170 : } 171 : } 172 : 173 : minNumber = atoi(valueString); 174 : 175 : return minNumber; 176 : } 177 : 178 : /** 179 : * 数値から文字列に変換して応答する。ただし、指定桁数に届かない分は先頭を0で埋める。 180 : * 181 : * @param valueString[] 変換後の文字列を格納する配列 182 : * @param aValue 変換元の数値 183 : * @param length 指定桁数 184 : */ 185 : void stringFromValueWithLength(char valueString[], int aValue, int length) 186 : { 187 : char formatString[10]; 188 : 189 : sprintf(formatString, "%%0%dd", length); 190 : sprintf(valueString, formatString, aValue); 191 : 192 : return; 193 : } 194 : 195 : /** 196 : * 配列中に重複要素があった場合、その要素が最初に出現するインデックスを応答する. 197 : * 198 : * @param valueArray[] 検査対象となる数値リスト 199 : * @param maxIndex 数値リストに対して参照できる最大のインデックス 200 : * @return 重複要素の格納場所を指すインデックス。重複要素がなければ-1を応答する。 201 : */ 202 : int getIndexOfDuplication(int valueArray[], int maxIndex) 203 : { 204 : int indexOfDuplication = -1; 205 : int index1, index2; // 注目している2要素を指すインデックス 206 : 207 : for (index1 = 0; index1 < maxIndex; index1++) 208 : { 209 : for (index2 = index1 + 1; index2 <= maxIndex; index2++) 210 : { 211 : if (valueArray[index1] == valueArray[index2]) 212 : { 213 : // 重複要素が見つかったため、ループから脱出する。 214 : indexOfDuplication = index1; 215 : index1 = MAX_ELEMENTS; 216 : index2 = MAX_ELEMENTS; 217 : } 218 : } 219 : } 220 : 221 : return indexOfDuplication; 222 : } 223 :
This document was generated by NanigashiBiyori on 2013/01/14 at 00:03:30.