Я предлагаю следующий алгоритм:1. Сначала рассмотрите все C[ i ]
как пустые гнезда.2. Для каждого я, где B[ i ] = 0
мы ставим C[ i ] = A[ i ]
3. Пройдите через массив слева направо , и для каждого i
, куда положите B[ i ] = -1
C[ j ] = A[ i ]
, где 0 <= j < i
- это наименьший индекс, для которого C[ j ]
все еще пуст.Если такого индекса нет, ответ невозможен.4. Пройдите массив справа налево , и для каждого i
, куда положите B[ i ] = 1
C[ j ] = A[ i ]
, где i < j < n
- индекс наибольшего , для которого C[ j ]
все еще пуст.Если такого индекса нет, ответ невозможен.
Почему мы помещаем A [i] в крайнее левое положение на шаге 2?Ну, мы знаем, что мы должны поставить его в какую-то позицию j A: [ 1, 2, 3 ]
B: [ 1, 1,-1 ]
Изначально C пусто: C:[ _, _, _ ]
У нас нет 0-х, поэтому давайте перейдем к шагу 2.Мы должны выбрать, поместить элемент A[ 2 ]
в C[ 0 ]
или C[ 1 ]
.Если мы поместим его , а не слева, мы получим следующую ситуацию:C: [ _, 3, _ ]
И ... К сожалению, мы не можем расположить элементы A[ 0 ]
и A[ 1 ]
из-за недостатка места :( Но , если мы поместим A [2] в крайнее левое положение, мы получимC: [ 3, _, _ ]
, и вполне возможно закончить алгоритмC: [ 3, 1, 2 ]
:) Сложность :То, что мы делаем, это трижды передаем массив, поэтому сложность O(3n) = O(n)
- линейная. Дальнейший пример:
A: [ 1, 2, 3 ]
B: [ 1, -1, -1 ]
Давайте пройдемся по алгоритму шаг за шагом:1. C: [ _, _, _ ]
2. Пусто, потому что нет 0-х в B
3. Поместите A[ 1 ]
и A[ 2 ]
в крайние левые пустые позиции:
C: [ 2, 3, _ ]
4.Помещение A[ 0 ]
в крайнее правое свободное (в данном примере единственное) свободное положение:
C: [ 2, 3, 1 ]
Какой ответ. Исходный код:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector< int > a;
vector< int > b;
vector< int > c;
int n;
bool solve ()
{
int i;
for( i = 0; i < n; ++i )
c[ i ] = -1;
for( i = 0; i < n; ++i )
if( b[ i ] == 0 )
c[ i ] = a[ i ];
int leftmost = 0;
for( i = 0; i < n; ++i )
if( b[ i ] == -1 )
{
for( ; leftmost < i && c[ leftmost ] != -1; ++leftmost ); // finding the leftmost free cell
if( leftmost >= i )
return false; // not found
c[ leftmost++ ] = a[ i ];
}
int rightmost = n - 1;
for( i = n - 1; i >= 0; --i )
if( b[ i ] == 1 )
{
for( ; rightmost > i && c[ rightmost ] != -1; --rightmost ); // finding the rightmost free cell
if( rightmost <= i )
return false; // not found;
c[ rightmost-- ] = a[ i ];
}
return true;
}
int main ()
{
cin >> n;
a.resize(n);
b.resize(n);
c.resize(n);
int i;
for( i = 0; i < n; ++i )
cin >> a[ i ];
for( i = 0; i < n; ++i )
cin >> b[ i ];
if( !solve() )
cout << "Impossible";
else
for( i = 0; i < n; ++i )
cout << c[ i ] << ' ';
cout << endl;
return 0;
}