ZOJ 1190 - Optimal Programs

  1  /*  Accepted 1190 C++ 00:00.48 28620K  */
  2  #include  < iostream >
  3 
  4  using   namespace  std;
  5 
  6  enum  { ADD  =   1 , DIV  =   2 , DUP  =   3 , MUL  =   4 , SUB  =   5 , maxStackSize  =   11  };
  7 
  8  inline  int  abs( int  n)
  9  {
 10       return  n  >   0   ?  n :  - n;
 11  }
 12 
 13  template  < class  T >
 14  class  stack
 15  {
 16  public :
 17      T x[maxStackSize];  char  p;
 18 
 19      stack() { p  =   - 1 ; }
 20       int  size() {  return  p  +   1 ;}
 21       bool  empty() {  return  p  ==   - 1 ; }
 22       void  push( const  T  &  item) { x[ ++ p]  =  item; }
 23       void  pop() { p -- ; }
 24       void  clear() { p  =   - 1 ; }
 25      T  &  top() {  return  x[p]; }
 26      
 27       void   operator   =  ( const  stack  &  st)
 28      {
 29          memcpy(x, st.x,  sizeof (st.x));
 30          p  =  st.p;
 31      }
 32  };
 33 
 34  struct  QUEUE
 35  {
 36       int  last;
 37       char  cnt, op;
 38      stack  < short >  st;
 39  }queue[ 888888 ];
 40 
 41  string  opSeq;
 42  int  n, x[ 10 ], y[ 10 ];
 43 
 44  void  getPath( int  i)
 45  {
 46       if (queue[i].last)
 47          getPath(queue[i].last);
 48      opSeq  +=  queue[i].op;
 49  }
 50 
 51  bool  checkOthers()
 52  {
 53       for ( int  i  =   1 ; i  <  n; i ++ )
 54      {
 55          stack  < short >  st;
 56          st.push(x[i]);
 57           int  a, b;
 58           for ( int  k  =   0 ; k  <  opSeq.size(); k ++ )
 59               switch (opSeq[k])
 60              {
 61                   case   1  :  // ADD
 62                      a  =  st.top(); st.pop();
 63                      b  =  st.top(); st.pop();
 64                       if (abs( int (a)  +   int (b))  >   30000 )
 65                           return   false ;
 66                      st.push(a  +  b);
 67                       break ;
 68                   case   2  :  // DIV
 69                      a  =  st.top(); st.pop();
 70                      b  =  st.top(); st.pop();
 71                       if (a  ==   0 return   false ;
 72                      st.push(b  /  a);
 73                       break ;
 74                   case   3  :  // DUP
 75                      st.push(st.top());  break ;
 76                   case   4  :  // MUL
 77                      a  =  st.top(); st.pop();
 78                      b  =  st.top(); st.pop();
 79                       if (abs( int (a)  *   int (b))  >   30000 )
 80                           return   false ;
 81                      st.push(a  *  b);
 82                       break ;
 83                   case   5  :  // SUB
 84                      a  =  st.top(); st.pop();
 85                      b  =  st.top(); st.pop();
 86                       if (abs( int (b)  -   int (a))  >   30000 )
 87                           return   false ;
 88                      st.push(b  -  a);
 89                       break ;
 90              }
 91           if (st.top()  !=  y[i])
 92               return   false ;
 93      }
 94       return   true ;
 95  }
 96 
 97  int  main()
 98  {
 99       int  program  =   0 ;
100       while ((cin  >>  n)  &&  n)
101      {
102          
103           for ( int  i  =   0 ; i  <  n; i ++ )
104              cin  >>  x[i];
105           for ( int  i  =   0 ; i  <  n; i ++ )
106              cin  >>  y[i];
107          
108          program ++ ;
109          cout  <<   " Program  "   <<  program  <<  endl;
110          
111           bool  empty_sequence  =   true ;
112           for ( int  i  =   0 ; i  <  n; i ++ )
113               if (x[i]  !=  y[i])
114              {
115                  empty_sequence  =   false break ;
116              }
117           if (empty_sequence)
118          {
119              cout  <<   " Empty sequence "   <<  endl  <<  endl;  continue ;
120          }
121          
122           int  front  =   - 1 , rear  =   0 ;
123           int  best  =  INT_MAX;  string  bestSeq( 10 255 );
124           bool  found  =   false ;
125          
126          queue[ 0 ].st.push(x[ 0 ]);
127          queue[ 0 ].last  =   0 ;
128          queue[ 0 ].cnt  =   0 ;
129          queue[ 0 ].op  =   0 ;
130           while (front  <  rear)
131          {
132              front ++ ;
133              
134               if (queue[front].cnt  >  best)
135                   continue ;
136              
137              stack  < short >  st  =  queue[front].st;
138              
139               if (st.size()  ==   1   &&  st.top()  ==  y[ 0 ])
140              {
141                  opSeq.clear();
142                  getPath(front);
143                   if (checkOthers())
144                  {
145                       if (queue[front].cnt  ==  best)
146                           if (opSeq  <  bestSeq)
147                              bestSeq  =  opSeq;
148                       if (queue[front].cnt  <  best)
149                      {
150                          best  =  queue[front].cnt;
151                          bestSeq  =  opSeq;
152                      }
153                      found  =   true ;
154                  }
155              }
156 
157               int  a, b;
158               if (queue[front].cnt  <   10 )
159              {
160                   // ADD
161                   if (st.size()  >   1 )
162                  {
163                      rear ++ ;
164                      queue[rear].st  =  st;
165                      queue[rear].op  =  ADD;
166                      queue[rear].cnt  =  queue[front].cnt  +   1 ;
167                      queue[rear].last  =  front;
168                      a  =  queue[rear].st.top(); queue[rear].st.pop();
169                      b  =  queue[rear].st.top(); queue[rear].st.pop();
170                      queue[rear].st.push(a  +  b);
171                       if (abs( int (a)  +   int (b))  >   30000 )
172                          rear -- ;
173                  }
174                  
175                   // DIV
176                   if (st.size()  >   1   &&  st.top()  !=   0 )
177                  {
178                      rear ++ ;
179                      queue[rear].st  =  st;
180                      queue[rear].op  =  DIV;
181                      queue[rear].cnt  =  queue[front].cnt  +   1 ;
182                      queue[rear].last  =  front;
183                      a  =  queue[rear].st.top(); queue[rear].st.pop();
184                      b  =  queue[rear].st.top(); queue[rear].st.pop();
185                      queue[rear].st.push(b  /  a);
186                  }
187                  
188                   // DUP
189                  rear ++ ;
190                  queue[rear].st  =  st;
191                  queue[rear].op  =  DUP;
192                  queue[rear].cnt  =  queue[front].cnt  +   1 ;
193                  queue[rear].last  =  front;
194                  queue[rear].st.push(st.top());
195                  
196                   // MUL
197                   if (st.size()  >   1 )
198                  {
199                      rear ++ ;
200                      queue[rear].st  =  st;
201                      queue[rear].op  =  MUL;
202                      queue[rear].cnt  =  queue[front].cnt  +   1 ;
203                      queue[rear].last  =  front;
204                      a  =  queue[rear].st.top(); queue[rear].st.pop();
205                      b  =  queue[rear].st.top(); queue[rear].st.pop();
206                      queue[rear].st.push(a  *  b);
207                       if (abs( int (a)  *   int (b))  >   30000 )
208                          rear -- ;
209                  }
210                  
211                   // SUB
212                   if (st.size()  >   1 )
213                  {
214                      rear ++ ;
215                      queue[rear].st  =  st;
216                      queue[rear].op  =  SUB;
217                      queue[rear].cnt  =  queue[front].cnt  +   1 ;
218                      queue[rear].last  =  front;
219                      a  =  queue[rear].st.top(); queue[rear].st.pop();
220                      b  =  queue[rear].st.top(); queue[rear].st.pop();
221                      queue[rear].st.push(b  -  a);
222                       if (abs( int (b)  -   int (a))  >   30000 )
223                          rear -- ;
224                  }
225              }
226          }
227 
228           if (found  ==   false )
229              cout  <<   " Impossible "   <<  endl;
230           else
231               for ( int  i  =   0 ; i  <  bestSeq.size(); i ++ )
232              {
233                   switch (bestSeq[i])
234                  {
235                       case   1  : cout  <<   " ADD " break ;
236                       case   2  : cout  <<   " DIV " break ;
237                       case   3  : cout  <<   " DUP " break ;
238                       case   4  : cout  <<   " MUL " break ;
239                       case   5  : cout  <<   " SUB " break ;
240                  }
241                  cout  <<  (i  ==  bestSeq.size()  -   1   ?   ' \n ' '   ' );
242              }
243          cout  <<  endl;
244          
245           for ( int  i  =   0 ; i  <=  rear; i ++ )
246              queue[i].st.clear();
247      }
248      
249       return   0 ;
250  }
251 

你可能感兴趣的:(ZOJ 1190 - Optimal Programs)