a[n]=0时一定无解,因为1-n的排列无论如何变换都是1-n的排列
a[n]!=0时,遇到0就交换a[i],a[i+1],这样可以满足只对i位置产生影响而不影响其余位置

#include <bits/stdc++.h>
#define ls p<<1
#define print pt
#define fi first
#define rs p<<1|1
#define se second
#define ins insert
#define getchar nc
#define pb push_back
#define lread rd<ll>
#define read rd<int>
#define mk make_pair
#define pf push_front
#define lowb(x) lower_bound(x)
#define uppb(x) upper_bound(x)
#define all(a) a.begin(),a.end()
#define lwb(a,b,c) lower_bound(a,b,c)
#define upb(a,b,c) upper_bound(a,b,c)
#define mset(x,a) memset(x,a,sizeof(x))
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define per(i,l,r) for(int i=(l);i>=(r);i--)
using namespace std;
using ll = long long;
using i128 = __int128;
using ld = long double;
using pii = pair<int,int>;
using ull = unsigned long long;
using pll = pair<long long,long long>;
const int base = 1331;
const int N = 1e6 + 7;
const int M = 1e4 + 7;
const int mod = 1e9 + 7;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const long long linf = 0x3f3f3f3f3f3f3f3f;
int dir[4][2]={1,0,0,1,-1,0,0,-1};
int dira[8][2]={{-1,0},{1,0},{0,-1},{0,1},{-1,-1},{-1,1},{1,-1},{1,1}};

//Overloading ostream
template <typename A, typename B> ostream &operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; }
template<typename C, typename D = typename enable_if<!is_same<C, string>::value, typename C::value_type>::type> ostream &operator<<(ostream &os, const C &v) { os << '{'; string sep; for (const D &x : v) os << sep << x, sep = ", "; return os << '}'; }
template<class Tuple, std::size_t N> struct TuplePrinter { static void print(std::ostream& os, const Tuple& t) { TuplePrinter<Tuple, N - 1>::print(os, t); os << ", " << std::get<N - 1>(t); } };
template<class Tuple> struct TuplePrinter<Tuple, 1> { static void print(std::ostream& os, const Tuple& t) { os << std::get<0>(t); } };
template<typename... Args> std::ostream& operator<<(std::ostream& os, const std::tuple<Args...>& t) { os << "("; TuplePrinter<decltype(t), sizeof...(Args)>::print(os, t); os << ")"; return os; }
template <typename T> ostream &operator<<(ostream &os, const set<T> &s) { os << '{'; string sep; for (const auto &x : s) os << sep << x, sep = ", "; return os << '}'; }
template <typename T> ostream &operator<<(ostream &os, const multiset<T> &s) { os << '{'; string sep; for (const auto &x : s) os << sep << x, sep = ", "; return os << '}'; }
template <typename K, typename V> ostream &operator<<(ostream &os, const map<K, V> &m) { os << '{'; string sep; for (const auto &p : m) os << sep << p.first << ": " << p.second, sep = ", "; return os << '}'; }
template <typename K, typename V> ostream &operator<<(ostream &os, const multimap<K, V> &m) { os << '{'; string sep; for (const auto &p : m) os << sep << p.first << ": " << p.second, sep = ", "; return os << '}'; }
template <typename T> ostream &operator<<(ostream &os, const unordered_set<T> &s) { os << '{'; string sep; for (const auto &x : s) os << sep << x, sep = ", "; return os << '}'; }
template <typename T> ostream &operator<<(ostream &os, const unordered_multiset<T> &s) { os << '{'; string sep; for (const auto &x : s) os << sep << x, sep = ", "; return os << '}'; }
template <typename K, typename V> ostream &operator<<(ostream &os, const unordered_map<K, V> &m) { os << '{'; string sep; for (const auto &p : m) os << sep << p.first << ": " << p.second, sep = ", "; return os << '}'; }
template <typename K, typename V> ostream &operator<<(ostream &os, const unordered_multimap<K, V> &m) { os << '{'; string sep; for (const auto &p : m) os << sep << p.first << ": " << p.second, sep = ", "; return os << '}'; }
template <typename T> ostream &operator<<(ostream &os, const stack<T> &s) { stack<T> temp = s; os << '['; string sep; while (!temp.empty()) { os << sep << temp.top(); temp.pop(); sep = ", "; } return os << ']'; }
template <typename T> ostream &operator<<(ostream &os, const queue<T> &q) { queue<T> temp = q; os << '['; string sep; while (!temp.empty()) { os << sep << temp.front(); temp.pop(); sep = ", "; } return os << ']'; }
template <typename T> ostream &operator<<(ostream &os, const priority_queue<T> &pq) { priority_queue<T> temp = pq; os << '['; string sep; while (!temp.empty()) { os << sep << temp.top(); temp.pop(); sep = ", "; } return os << ']'; }
template <typename T, size_t N> ostream &operator<<(ostream &os, const array<T, N> &a) { os << '{'; string sep; for (const auto &x : a) os << sep << x, sep = ", "; return os << '}'; }
template <typename T> ostream &operator<<(ostream &os, const deque<T> &dq) { os << '{'; string sep; for (const auto &x : dq) os << sep << x, sep = ", "; return os << '}'; }

//Debug
void dbg_out() { cerr << endl; }
template <typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cerr << ' ' << H; dbg_out(T...); }
#ifndef ONLINE_JUDGE
#define dbg(...) cerr << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
#define dbg(...)
#endif

//Fast read
inline char nc() { static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++; }
template<class T> T rd() { int f = 0, c; T x = 0; while (!isdigit(c = nc())) f |= c == '-'; x = (c ^ 48); while (isdigit(c = nc())) x = x * 10 + (c ^ 48); if (f) x = -x; return x; }
template<class T> void pt(T x, int c = -1) { if (x < 0) putchar('-'), x = -x; if (x > 9) pt(x / 10); putchar(x % 10 + 48); if (c != -1) putchar(c); }

ll n,m;
void solve(){ 
  cin>>n;
  vector<int> a(n+1,0),ans(n+1);
  rep(i,1,n){char c;cin>>c;a[i]=c^48;}
  if(!a[n]){
    cout<<-1;return ;
  }
  rep(i,1,n)ans[i]=i;
  rep(i,1,n)if(!a[i])swap(ans[i],ans[i+1]);
  rep(i,1,n)cout<<ans[i]<<' ';
  return;
}
int main(){
  ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  // cout << fixed << setprecision(3);
  // cout << right << left << setw(3);
  // int _; _ = read(); while (_--)
  solve();
  return 0;
}