Problem H. Walaweh

Problem Author: Felix Halim

Soal ini cukup merepotkan, bukan karena algoritmanya yang susah, melainkan karena implementasi program rekursi/simulasinya yang harus dibuat dengan hati-hati (mudah salah). Hanya dua tim yang mencoba menyelesaikan soal ini, namun tidak ada yang berhasil.



Solusi C/C++
oleh Felix Halim
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <stdlib.h>
using namespace std;

string walaweh(long long L, long long N){
  string left = "", right = "";
  while (L-- > 1){
    long long len = 1LL << L;
    switch ((L-1)%8){
      case 0: if (N < len){ right = "0" + right; } else { right = "1" + right; N -= len; } break;
      case 1: if (N < len){ left = left + "0";   } else { left = left + "1"; N -= len;   } break;
      case 2: if (N < len){ right = "1" + right; } else { right = "0" + right; N -= len; } break;
      case 3: if (N < len){ left = left + "1";   } else { left = left + "0"; N -= len;   } break;
      case 4: if (N < len){ right = "0" + right; } else { right = "1" + right; N = len - (N-len) - 1; } break;
      case 5: if (N < len){ left = left + "0";   } else { left = left + "1"; N = len - (N-len) - 1;   } break;
      case 6: if (N < len){ right = "1" + right; } else { right = "0" + right; N = len - (N-len) - 1; } break;
      case 7: if (N < len){ left = left + "1";   } else { left = left + "0"; N = len - (N-len) - 1;  } break;
    }
  }
  return left + (N?"1":"0") + right;
}

long long seq(char *w, int left, int right){
  if (left == right) return w[left] - '0' + 1;

  long long L = right-left, len = 1LL << L;
  switch ((L-1)%8){
    case 0: return seq(w,left,right-1) + ((w[right]=='1')? len : 0);
    case 1: return seq(w,left+1,right) + ((w[left]=='1')? len : 0);
    case 2: return seq(w,left,right-1) + ((w[right]=='0')? len : 0);
    case 3: return seq(w,left+1,right) + ((w[left]=='0')? len : 0);
    case 4: return (w[right]=='1')? (2*len - seq(w,left,right-1) + 1) : seq(w,left,right-1);
    case 5: return (w[left]=='1')? (2*len - seq(w,left+1,right) + 1) : seq(w,left+1,right);
    case 6: return (w[right]=='0')? (2*len - seq(w,left,right-1) + 1) : seq(w,left,right-1);
    case 7: return (w[left]=='0')? (2*len - seq(w,left+1,right) + 1) : seq(w,left+1,right);
  }
}

int main(){
  char s[100];
  long long L,N;

  while (scanf("%s",s)!=EOF){
    if (s[0]=='W'){
      scanf("%I64d %I64d",&L,&N);
      printf("%s\n",walaweh(L,N-1).c_str());
    } else {
      scanf("%s",s);
      printf("%I64d\n",seq(s,0,strlen(s)-1));
    }
  }
}

Solusi JAVA
oleh Felix Halim
import java.util.*;
import java.io.*;

public class Walaweh {
  String wal(int L, long N){
    if (L==1) return ""+N;
    long H = 1L << (L-1);
    switch ((L-2)%8){
      case 0: return (N<H)? (wal(L-1,N)+"0") : (wal(L-1,N-H)+"1");
      case 1: return (N<H)? ("0"+wal(L-1,N)) : ("1"+wal(L-1,N-H));
      case 2: return (N<H)? (wal(L-1,N)+"1") : (wal(L-1,N-H)+"0");
      case 3: return (N<H)? ("1"+wal(L-1,N)) : ("0"+wal(L-1,N-H));
      case 4: return (N<H)? (wal(L-1,N)+"0") : (wal(L-1,H-(N-H)-1)+"1");
      case 5: return (N<H)? ("0"+wal(L-1,N)) : ("1"+wal(L-1,H-(N-H)-1));
      case 6: return (N<H)? (wal(L-1,N)+"1") : (wal(L-1,H-(N-H)-1)+"0");
      case 7: return (N<H)? ("1"+wal(L-1,N)) : ("0"+wal(L-1,H-(N-H)-1));
    }
    return "error";
  }

  long seq(String S, int i, int j){
    if (i==j) return S.charAt(i)-'0';
    long N = 1L << (j-i), ret = 0, add = 0;
    switch ((j-i-1)%8){
      case 0 : return (S.charAt(j)=='0')? seq(S,i,j-1) : (N + seq(S,i,j-1));
      case 1 : return (S.charAt(i)=='0')? seq(S,i+1,j) : (N + seq(S,i+1,j));
      case 2 : return (S.charAt(j)=='1')? seq(S,i,j-1) : (N + seq(S,i,j-1));
      case 3 : return (S.charAt(i)=='1')? seq(S,i+1,j) : (N + seq(S,i+1,j));
      case 4 : ret = seq(S,i,j-1); if (S.charAt(j)=='1') ret = N-ret-1 + N; break;
      case 5 : ret = seq(S,i+1,j); if (S.charAt(i)=='1') ret = N-ret-1 + N; break;
      case 6 : ret = seq(S,i,j-1); if (S.charAt(j)=='0') ret = N-ret-1 + N; break;
      case 7 : ret = seq(S,i+1,j); if (S.charAt(i)=='0') ret = N-ret-1 + N; break;
    }
    return ret;
  }

  void solve() throws Exception {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    for (String line; (line = br.readLine())!=null; ){
      String[] s = line.split(" ");
      if (s[0].charAt(0)=='W'){
        int L = Integer.parseInt(s[1]);
        long N = Long.parseLong(s[2]);
        bw.write(wal(L, N-1) + "\n");
      } else {
        bw.write((seq(s[1],0,s[1].length()-1)+1) + "\n");
      }
    }
    br.close();
    bw.close();
  }

  public static void main(String[] args) throws Exception {
    new Walaweh().solve();
  }
}