ACM ICPC Latin America 2011 – I – In Braille

/* 
 * @author: vudduu - Edwin Guzman
 * @problem: Problem I - In Braille
 * @contest: ACM ICPC Latin America Regional 2011
 */
#include <iostream>
#include <sstream>
#include <utility>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <functional>
#include <algorithm>
#include <numeric>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <stdio.h>
#include <string.h>
using namespace std;

#define FOR(i,a,b)  for(int i=(a),_##i=(b);i<_##i;++i)
#define F(i,a)      FOR(i,0,a)
#define ALL(x)      x.begin(),x.end()
#define PB          push_back
#define MP          make_pair
#define S           size()
typedef long long   LL;

string s1[] = {".*", "*.", "*.", "**", "**", "*.", "**", "**", "*.", ".*"};
string s2[] = {"**", "..", "*.", "..", ".*", ".*", "*.", "**", "**", "*."};

char ch[305];
char num[105];
char s[3][305];

int it;

void lee(int & n){
   it = n = 0;
   gets(ch);
   while(ch[it]) n = n*10 + ch[it++]-'0';
}

int main(){
   int n;
   lee(n);
   while(n){
      gets(ch);
      it = 0;
      if(ch[0] == 'S'){
         gets(num);
         for(int i=0; i<n ;i++){
            if(i) s[0][it] = ' ', s[1][it] = ' ', s[2][it++] = ' ';
            char numaux = num[i]-'0';
            s[0][it] = s1[ numaux ][0];
            s[1][it] = s2[ numaux ][0];
            s[2][it++] = '.';
            s[0][it] = s1[ numaux ][1];
            s[1][it] = s2[ numaux ][1];
            s[2][it++] = '.';
         }
         s[0][it] = s[1][it] = s[2][it] = 0;
         puts(s[0]);
         puts(s[1]);
         puts(s[2]);
      }
      else{
         for(int i=0; i<3 ;i++)
            gets(s[i]);
         for(int i=0; i<n ;i++){
            int it1 = i*3, j;
            for(j=0; j<10 ;j++){
               if(s[0][it1] == s1[j][0]) if(s[0][it1+1] == s1[j][1])
                  if(s[1][it1] == s2[j][0]) if(s[1][it1+1] == s2[j][1])
                     break;
            }
            num[it++] = j+'0';
         }
         num[it] = 0;
         puts(num);
      }
      lee(n);
   }
}

ACM ICPC Latin America 2011

You can test your solution in the ACM ICPC Live Archive.

Links:
Problemset + Dataset
Live Archive – ACM ICPC Latin America 2011
Final Results Latin America

Problems solved:
A – Army Buddies (Data Structure, List) –> C++ Code
B – Ball Stacking (DP) –> C++ Code
– C – Candy’s Candy (Math)
– E – Electrical Pollution (Graph Traversal)
– F – File Retrieval (Stack, Suffix Array)
– G – Garden Fence (Sweep Line)
– H – Hedge Mazes (Graph Bridges, Strongly Connected Components)
I – In Braille (Implementation) –> C++ Code
J – Jupiter Atacks! (RMQ, Interval Tree) –> C++ Code
K – King’s Poker (implementation) –> C++ Code

Thanks for help Gareve and fetofs.

A – Ants Colony – ACM ICPC Latin America 2010

This is a typical case of LCA. Example (Sample input 1):

6                Tree:   0
0 8                     / 
1 7                    1   4
1 9                   /    
0 3                  2   3   5
4 2
4
2 3
5 2
1 4
0 3

(2 3):

 sum = 0      sum = 0    sum = p[a] + p[b] = 7 + 9 = 16
    x           x           x       
   /          /          /       
  1   x   =   1   x   = ab1   x  
 /         /         /        
2   3   x   a2 b3   x   x   x   x

(5 2):

 sum = 0      sum = 0  sum=p[a]+p[b]= 9 + 11 = 20
                              2+7         8+3

    0           0           0           0ab       
   /          /          /          /       
  1   4   =   1   4   =   1a  4b  =   x   x   
 /         /         /         /        
2a  3  b5   2a  x  b5   x   x   x   x   x   x

This is my implementation:

#include <iostream>
#include <vector>
#include <math.h>
using namespace std;

#define FOR(i,a,b)  for(int i=(a),_##i=(b);i<_##i;++i)
#define F(i,a)      FOR(i,0,a)
#define PB          push_back
#define MP          make_pair
#define S           size()
typedef long long   LL;

int TreeDad[100000], TreeDadH[100000];
int TreeLevel[100000];
LL TreeLen[100000];
vector<vector<int> > TreeSons(100000);

int N, sqrtL;

void build_tree(int node){
  if(!(TreeLevel[node] % sqrtL))
    TreeDadH[node] = TreeDad[node];
  else
    TreeDadH[node] = TreeDadH[ TreeDad[node] ];
  F(i, TreeSons[node].S)
    build_tree(TreeSons[node][i]);
}

int LCA(int x, int y) {
  while (TreeDadH[x] != TreeDadH[y]){
    if(TreeLevel[x] > TreeLevel[y]) x = TreeDadH[x];
    else y = TreeDadH[y];
  }
  while (x != y){
    if (TreeLevel[x] > TreeLevel[y]) x = TreeDad[x];
    else y = TreeDad[y];
  }
  return x;
}

int main(){
  int l, a, Q, s, t;
  while(scanf("%d", &N) && N){
    F(i, N) TreeSons[i].clear();
    int MaxLevel = 0;
    FOR(i, 1, N){
      scanf("%d %d", &a, &l);
      TreeDad[i] = a;
      TreeLen[i] = TreeLen[a] + LL(l);
      TreeLevel[i] = TreeLevel[a] + 1;
      TreeSons[a].PB(i);
      MaxLevel = max(MaxLevel, TreeLevel[i]);
    }
    sqrtL = sqrt(MaxLevel);
    build_tree(0);

    scanf("%d", &Q);
    F(i, Q){
      if(i) printf(" ");
      scanf("%d %d", &s, &t);
      printf("%lld", TreeLen[s] + TreeLen[t] - (TreeLen[LCA(s, t)]*2LL) );
    }
    printf("n");
  }
}

D – Digits Count – ACM ICPC Latin America 2010

This problem was simple, logic was as follows.
Not seek from a to b, look of 0 to a and then from 0 to b.

0 to a = {array A}
0 to b = {array B}

And subtract that obtained with a. arrayResult = arrayB – arrayA If we accept leading zeros.

              0   1   2   3   4   5   6   7   8   9
0 to 9 =     {1   1   1   1   1   1   1   1   1   1}
00 to 99 =   {20  20  20  20  20  20  20  20  20  20}
000 to 999 = {300 300 300 300 300 300 300 300 300 300}

Understanding.

              0   1   2   3   4   5   6   7   8   9
10 to 19 =   {1   1   1   1   1   1   1   1   1   1} (0 to 9)
           + {0   10  0   0   0   0   0   0   0   0} (1 repeated ten times)
         =   {1   11  1   1   1   1   1   1   1   1} (Total)

If we have a number ending in 9 we subtract from 10 to 10.

0 to 59 = (0 to 9) + (10 to 19) + (20 to 29) + ... + (50 to 59)

And.

              0   1   2   3   4   5   6   7   8   9
100 to 199 = {20  20  20  20  20  20  20  20  20  20} (00 to 99)
           + {0   100 0   0   0   0   0   0   0   0 } (1 repeated 100 times)
           = {20  120 20  20  20  20  20  20  20  20} (Total)

Now need to be in positions which have nine, this can be done with brute force. Using this we can make several solutions, here is an acceptable solution.

#include <iostream>
#include <vector>
using namespace std;

int tens[]  = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
int nines[] = {0, 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 2000000000};

int hmNines(int x){
 for(int i=1; i<9 ;i++){
  if(x%tens[i] != nines[i]){
   if(x > nines[i-1]) return i-1;
   else return i-2;
  }
 }
 return 7;
}

vector<int> countDig(int a){
 vector<int> dig(10, 0);
 while(a > 0){
  int n = hmNines(a);
  for(int i=a/tens[n]; i ;i/=10)
   dig[ i%10 ] += tens[n];
  if(n) for(int i=0; i<10 ;i++)
   dig[ i ] += tens[n-1] * n;
  a -= tens[n];
 }
 return dig;
}

int main() {
 int a, b;
 scanf("%d %d", &a, &b);
 while(a){
  vector<int> digA = countDig(a-1);
  vector<int> digB = countDig(b);
  for(int i=0; i<10 ;i++)
   digB[i] -= digA[i];
  printf("%d", digB[0]);
  for(int i=1; i<10 ;i++)
   printf(" %d", digB[i]);
  printf("n");
  scanf("%d %d", &a, &b);
 }
}

J – Jollo – ACM ICPC Latin America 2010

This problem could be solved easily using brute force, then is my solution using brute force.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool solve(vector<int> v1, vector<int> v2) {
    sort(v2.begin(), v2.end());
    int c;
    do {
        c = 0;
        if (v2[0] > v1[0]) c++;
        if (v2[1] > v1[1]) c++;
        if (v2[2] > v1[2]) c++;
        if (c < 2) return false;
    }
    while (next_permutation(v2.begin(), v2.end()));
    return true;
}

int main() {
    int x, y, z;
    vector<int> v1(3), v2(3);
    scanf("%d %d %d %d %d", &v1[0], &v1[1], &v1[2], &v2[0], &v2[1]);
    while (v1[0]) {
        z = -1;
        sort(v1.begin(), v1.end());
        vector<bool> vis(52, true);
        vis[v1[0]] = vis[v1[1]] = vis[v1[2]] = false;
        vis[v2[0]] = vis[v2[1]] = false;
        for (int i=1; i<=52 ;i++) {
            if (vis[i]) {
                v2[2] = i;
                if (solve(v1, v2)) {
                    z = i;
                    i = 53;
                }
            }
        }
        printf("%dn", z);
        scanf("%d %d %d %d %d", &v1[0], &v1[1], &v1[2], &v2[0], &v2[1]);
    }
}

F – Flowers Flourish from France – ACM ICPC Latin America 2010

This was one of the easiest problems of the competition.
The solution is obtained looking at all the letters after a space, although in my case solution to solve for ‘N’ spaces between words.

#include <iostream>
using namespace std;
char ops(char ch){
    if(ch < 'a') return ch+32;
    return ch;
}
int main() {
    string s;
    getline(cin,s,'n');
    while(s != "*"){
        int i = 0, n = s.size();
        char ch = ops(s[0]);
        bool flag = true;
        while(s[i] != ' ' && i < n) i++;
        while(i < n){
            i++;
            if(ch != ops(s[i])) flag = false;
            while(s[i] != ' ' && i < n) i++;
        }
        if(flag) puts("Y");
        else puts("N");
        getline(cin, s, 'n');
    }
}

B – Bingo! – ACM ICPC Latin America 2010

The logic of this problem was very simple, should undertake all periodization.
The following example is the test case 2:

5 4
5 3 0 1

vb[] = {5} // (5) entered first in the list
vn[] = {0 0 0 0 0 0}

vb[] = {5 3} // (3)
vn[] = {0 0 1 0 0 0} // abs(3-5) = 1

vb[] = {5 3 0} // (0)
vn[] = {0 0 1 1 0 1} // abs(3-0) = 3, abs(5-0) = 5

vb[] = {5 3 0 1} // (1)
vn[] = {0 1 1 1 1 1} // abs(1-0) = 1, abs(5-1) = 4, abs(3-1) = 2

With this we have all the numbers generated.
This is my implementation in c:

#include <iostream>
#include <cmath>
#include <functional>
#include <string>
#include <vector>
using namespace std;
int main() {
    int n, b;
    scanf("%d %d", &n, &b);
    while(n){
        vector<bool> vn(n+1, 0);
        int vb[b], c = 0;
        for(int i=0;i<b;i++){
            scanf("%d", &vb[i]);
            for(int j=0;j<i;j++){
                int aux = abs(vb[i]-vb[j]);
                if(!vn[aux]){
                    vn[aux] = 1;
                    c++;
                }
            }
        }
        if(c >= n) puts("Y");
        else puts("N");
        scanf("%d %d", &n, &b);
    }
}