SPOJ 416 Divisibility by 15 细节题

一个结论:一个数,如果它的所有数字之和能被3整除,那么这个数也能被3整除。

最后一位肯定是0或者5,如果没有就impossible。

剩下的就是,如何删除尽量少的数,使所有数字之和为3的倍数。

情况比较多,注意考虑全面。

  1 #include <cstdio>

  2 #include <cstring>

  3 #include <cstdlib>

  4 

  5 using namespace std;

  6 

  7 const int MAXN = 1010;

  8 

  9 char str[MAXN];

 10 int cnt[14];

 11 int end;

 12 

 13 void OutPut()

 14 {

 15     bool ok = false;

 16     for ( int i = 9; i > 0; --i )

 17     {

 18         for ( int j = 0; j < cnt[i]; ++j )

 19         {

 20             if (i) ok = true;

 21             printf( "%d", i );

 22         }

 23     }

 24 

 25     if ( ok )

 26     {

 27         for ( int i = 0; i < cnt[0]; ++i )

 28             putchar('0');

 29     }

 30 

 31     if ( end == 0 ) puts("0");

 32     else puts("5");

 33 

 34     return;

 35 }

 36 

 37 bool solved( int sum )

 38 {

 39     int left = sum % 3;

 40 

 41     //删一个数

 42     if ( cnt[left] )

 43     {

 44         --cnt[left];

 45         return true;

 46     }

 47     if ( cnt[3 + left] )

 48     {

 49         --cnt[left + 3];

 50         return true;

 51     }

 52     if ( cnt[ 6 + left ] )

 53     {

 54         --cnt[ 6 + left ];

 55         return true;

 56     }

 57 

 58     //删两个数

 59     if ( left == 1 )

 60     {

 61         if ( cnt[2] >= 2 )

 62         {

 63             cnt[2] -= 2;

 64             return true;

 65         }

 66         if ( cnt[2] && cnt[5] )

 67         {

 68             --cnt[2], --cnt[5];

 69             return true;

 70         }

 71         if ( cnt[5] >= 2 )

 72         {

 73             cnt[5] -= 2;

 74             return true;

 75         }

 76         if ( cnt[2] && cnt[8] )

 77         {

 78             --cnt[2], --cnt[8];

 79             return true;

 80         }

 81         if ( cnt[5] && cnt[8] )

 82         {

 83             --cnt[5], --cnt[8];

 84             return true;

 85         }

 86         if ( cnt[8] >= 2 )

 87         {

 88             cnt[8] -= 2;

 89             return true;

 90         }

 91     }

 92     else

 93     {

 94         if ( cnt[1] >= 2 )

 95         {

 96             cnt[1] -= 2;

 97             return true;

 98         }

 99         if ( cnt[1] && cnt[4] )

100         {

101             --cnt[1], --cnt[4];

102             return true;

103         }

104         if ( cnt[4] >= 2 )

105         {

106             cnt[4] -= 2;

107             return true;

108         }

109         if ( cnt[1] && cnt[7] )

110         {

111             --cnt[1], --cnt[7];

112             return true;

113         }

114         if ( cnt[4] && cnt[7] )

115         {

116             --cnt[4], --cnt[7];

117             return true;

118         }

119         if ( cnt[7] >= 2 )

120         {

121             cnt[7] -= 2;

122             return true;

123         }

124     }

125     return false;

126 }

127 

128 int main()

129 {

130     //freopen( "in.txt", "r", stdin );

131     //freopen( "out.txt", "w", stdout );

132     int T;

133     scanf( "%d", &T );

134     while ( T-- )

135     {

136         scanf( "%s", str );

137         memset( cnt, 0, sizeof(cnt) );

138         for ( int i = 0; str[i]; ++i )

139             ++cnt[ str[i] - '0' ];

140 

141         if ( !cnt[0] && !cnt[5] )

142         {

143             puts("impossible");

144             continue;

145         }

146 

147         int sum = 0;

148         for ( int i = 1; i < 10; ++i )

149             sum += i * cnt[i];

150 

151         if ( cnt[0] )

152             --cnt[0], end = 0;

153         else

154             --cnt[5], end = 5;

155 

156         if ( sum % 3 == 0 )

157         {

158             if ( sum == 0 )

159             {

160                 puts("0");

161                 continue;

162             }

163             OutPut();

164         }

165         else

166         {

167             if ( solved( sum ) ) OutPut();

168             else puts("impossible");

169         }

170     }

171     return 0;

172 }

 

你可能感兴趣的:(visibility)