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 }

 

posted @ 2013-07-29 21:39  冰鸮  阅读(237)  评论(0编辑  收藏  举报