UVA Problem 11988 – Broken Keyboard (a.k.a. Beiju Text) Solution

UVA Problem 11988 – Broken Keyboard (a.k.a. Beiju Text) Solution:

Click here to go to this problem in uva Online Judge.

Solving Technique:

The input may be classified into three things. One is append to beginning represented with ‘[‘, another is append to end represented with ‘]’ and the other types any other character except above mentioned. The other character are appended to the next position of last inserted character.

So task is move all characters following ‘[‘ to beginning until ‘]’ is found or end of string is reached. Similar logic applies to ‘]’ character. Also it is a recursive definition, keep applying this logic for all the following third brackets.

Other ideas:

Some other ideas to solve this problem can be, formatting the input to remove useless brackets then create a tree from inputs and perform in-order traversal to get the result. Another idea is create a linked list of strings.

Code Explanation:

I may later ( takes quite bit of time to create graphics ) provide a graphical representation of inserting in the doubly linked list ( 2nd code ). Meanwhile I provided a commented version ( 2nd code ) to make it a little easier to understand.

Here I have provided two codes. Both are linked list implementations. First one is singly linked list with no tail pointer( rather inefficient although I try to reduce some complexity by Boolean flag checking to reduce traversing the list to find tail pointer ). It is not able to keep track of tail pointer efficiently. Need to do some traversing ( some times almost the whole linked list ) to find the tail pointer.

The second implementation is doubly linked list with tail node as the tail pointer. The tail pointer has character has 0 which is ASCII decimal code for NULL character. I use this to stop printing otherwise a space character is printed at the end of output.

Important:  Be sure to add or print a new line after each output unless otherwise specified. The outputs should match exactly because sometimes even a space character causes the answer to be marked as wrong answer. Please compile with c++ compiler as some of my codes are in c and some in c++.

More Inputs of This Problem on uDebug.

Input:

This_is_a_[Beiju]_text
[[]][][]Happy_Birthday_to_Tsinghua_University

Output:

BeijuThis_is_a__text
Happy_Birthday_to_Tsinghua_University

Code Singly Linked list Without Tail:

/**
* Author:    Asif Ahmed
* Site:      https://quickgrid.wordpress.com
* Problem:   UVA 11988 - broken keyboard
* Technique: Singly Linked List with no
*            tail Pointer(slow).
*/

#include<stdio.h>
#include<string.h>

#define N 100000

static char input[N];

struct vertex{
char c;
struct vertex* next;
};

typedef struct vertex node;

node* insertNode(node* n, char c){

node* temp = new node();
temp->c = c;
temp->next = n->next;
n->next = temp;

return temp;
}

void printList( node* dummy ){

node* tmp = dummy;

while( tmp = tmp->next )
putchar( tmp->c );

printf("\n");
}

int main(){

//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);

while( gets(input) ){

node* dummy = new node();
dummy->next = NULL;
node* cur = dummy;

node* tail = dummy;

bool rightopen = false;

for(int i = 0; input[i]; ++i){

if( input[i] == '[' ){
cur = dummy;
rightopen = true;
continue;
}
if( input[i] == ']' ){
rightopen = false;

node *tmp = tail;

while( tmp->next != NULL )
tmp = tmp->next;

tail = cur = tmp;
continue;
}

cur = insertNode(cur, input[i] );
if( !rightopen )
tail = cur;
}

printList( dummy );

}

return 0;
}

Code Doubly Linked list With Tail Pointer:

/**
* Author:    Asif Ahmed
* Site:      https://quickgrid.wordpress.com
* Problem:   UVA 11988 - broken keyboard
* Technique: Doubly Linked List with
*            dummy tail node as Pointer.
*/

#include<stdio.h>
#include<string.h>

#define N 100000

static char input[N];

// Doubly linked list.
struct vertex{
char c;
struct vertex* next;
struct vertex* prev;
};
typedef struct vertex node;

node* insertNode(node* n, char c){

// Create the new node to hold current character.
node* temp = new node();
temp->c = c;

// Create forward connection from this created node
// to the next node of passed in node (n).
// Also create backward connection from the passed
// in node to current node.
temp->next = n->next;
n->next->prev = temp;

// Create forward connection from passed in node (n) to the
// newly created node (temp).
// Also create backward connection from created node to the
// passed in node.
n->next = temp;
temp->prev = n;

// return the pointer to the current node.
return temp;
}

void printList( node* dummy ){

// Dummy (head) is not a part of output.
node* tmp = dummy->next;

// Since I use tail pointer, check if its tail.
while( tmp->c ){
putchar( tmp->c );
tmp = tmp->next;
}

printf("\n");
}

int main(){

//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);

while( gets(input) ){

// Dummy node is just to keep track of beginning.
// It does not contain any input character.
// Tail is used to insert before the last node.
// Tail is also another dummy node keeps track of
// the end.
node* dummy = new node();
node* tail = new node();

// NULL may not be necessary since I use tail character
// checking to stop printing.
tail->prev = dummy;
dummy->next = tail;
tail->next = NULL;
dummy->prev = NULL;

// Set current node to dummy (beginning). Set tail
// to NULL character equivalent ASCII value.
node* cur = dummy;
tail->c = 0;

for(int i = 0; input[i]; ++i){

// Update node pointer to beginning based on bracket.
// If not bracket use previous pointer location.
if( input[i] == '[' ){
cur = dummy;
continue;
}
if( input[i] == ']' ){
cur = tail->prev;
continue;
}

cur = insertNode(cur, input[i] );
}

// Print output characters one by one.
printList( dummy );

}

return 0;
}

Simple Polynomial data structure and Calculator for single variable

Explanation:

The first code takes an integer for the value of the variable and the next one takes a double for the value of variable and produces value of the function.

I have commented the second code to make it easy. Pun intended on lines 144 to 147.

Calculates an equation with given value of the variable. If the equation is, $f(x) = -50x^{-3} +3x -40x^2 +10x^{-5} -7x^{10}$

then for, $x = -3, \ f(x) = -413710.189300 \\ x = -2, \ f(x) = -7328.062500 \\ x = -1, \ f(x) = -10.000000 \\ x = 0, \ \ \ f(x) = \ \ \ Undefined \\ x = 1, \ \ \ f(x) = -84.000000 \\ x = 2, \ \ \ f(x) = -7327.937500 \\ x = 3, \ \ \ f(x) = -413695.810700 \\$

(Pease Test this code before using, I haven’t done much testing). Check against this site. To use this from console comment freopen lines. Otherwise make two txt files named input and output in the same directory as the cpp file and follow the given equation input format.

Input:
-50x^-3 +3x^+1 -40x^+2 +10x^-5 -7x^+10
0
y
-3
y
-2
y
-1
y
0
y
1
y
2
y
3
n
Output:
-50x^-3 +3x^+1 -40x^+2 +10x^-5 -7x^+10
Calculate value of Equation for given value (y/n)?
Enter value for the variable.
>>	 -413710.189300
Calculate value of Equation for given value (y/n)?
Enter value for the variable.
>>	 -7328.062500
Calculate value of Equation for given value (y/n)?
Enter value for the variable.
>>	 -10.000000
Calculate value of Equation for given value (y/n)?
Enter value for the variable.
Sorry Try something different
Calculate value of Equation for given value (y/n)?
Enter value for the variable.
>>	 -84.000000
Calculate value of Equation for given value (y/n)?
Enter value for the variable.
>>	 -7327.937500
Calculate value of Equation for given value (y/n)?
Enter value for the variable.
>>	 -413695.810700
Calculate value of Equation for given value (y/n)?
Exiting...

Code:

/**
* Author:    Asif Ahmed
* Site:      https://quickgrid.wordpress.com
* Problem:   Simple Polynomial data structure and
*            Calculator for single variable.
*/

#include<stdio.h>
#include<string.h>
#include<math.h>

#define N 512

char input[N];

struct PolynomialEquation{

char sign;
char signExponent;
int exponent;
char variable;
int constant;

struct PolynomialEquation *next;
};
typedef struct PolynomialEquation node;

node* insertNode(node* current, char sign, int constant, char variable, char signExponent, int exponent){

node* temp = new node();

temp->sign = sign;
temp->signExponent = signExponent;
temp->exponent = exponent;
temp->variable = variable;
temp->constant = constant;

temp->next = NULL;
current->next = temp;
current = temp;

return current;
}

void printEquation(node* dummy){
node* tmp = dummy->next;
while( tmp != NULL ){
printf("%c%d%c^%c%d ", tmp->sign, tmp->constant, tmp->variable, tmp->signExponent, tmp->exponent);
tmp = tmp->next;
}
printf("\n");
}

void calculateEquation(node* dummy, int var){

double sum = 0;
bool calculable;

node* tmp = dummy->next;
while( tmp != NULL ){

double constantValue = 0, variableValue = 0;
calculable = true;

constantValue = tmp->constant;
if(tmp->sign == '-')
constantValue *= -1;

variableValue = pow(var, tmp->exponent);
if(tmp->signExponent == '-'){
if(variableValue)
variableValue = (double) 1 / variableValue;
else
calculable = false;
}

sum = sum + variableValue * constantValue;
tmp = tmp->next;

if(!calculable){
printf("Sorry Try something different\n");
break;
}

}

if(calculable)
printf(">>\t %f\n", sum);

}

int main(){

// Comment these lines to do I/O operation in console.
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);

char sign;
char signExponent;
int exponent;
char variable;
int constant;

node* dummy = new node();
dummy->variable = '\$';
node* current = dummy;

while( scanf("%c%d%c%*c%c%d", &sign, &constant, &variable, &signExponent, &exponent ) == 5){
getchar();
current = insertNode(current, sign, constant, variable, signExponent, exponent);
}

printEquation(dummy);

while(1){
printf("Calculate value of Equation for given value (y/n)?\n");

char choice = getchar();

if( choice == 'y' ){
printf("Enter value for the variable.\n");

int variableValue;
scanf("%d", &variableValue);
getchar();

calculateEquation(dummy, variableValue);
}else{
printf("Exiting...\n");
break;
}
}

return 0;
}

Working with float numbers:

If the equation is, $f(x) = - 4x^{2} - 4x - 9$

Input:
+4x^+2 -4x^+1 -9x^+0
0
y
5
y
2.5
y
1.25
y
1.875
n
Output:
+4x^+2 -4x^+1 -9x^+0
Calculate value of Equation for given value (y/n)?
Enter value for the variable:
>>	 71.000000
Calculate value of Equation for given value (y/n)?
Enter value for the variable:
>>	 6.000000
Calculate value of Equation for given value (y/n)?
Enter value for the variable:
>>	 -7.750000
Calculate value of Equation for given value (y/n)?
Enter value for the variable:
>>	 -2.437500
Calculate value of Equation for given value (y/n)?
Exiting...

Code for float:

/**
* Author:    Asif Ahmed
* Site:      https://quickgrid.wordpress.com
* Problem:   Simple Polynomial data structure and
*            Calculator with single variable.
*/

#include<stdio.h>
#include<string.h>
#include<math.h>

#define N 512

char input[N];

struct PolynomialEquation{

char sign;
char signExponent;
int exponent;
char variable;
int constant;

struct PolynomialEquation *next;
};
typedef struct PolynomialEquation node;

node* insertNode(node* current, char sign, int constant, char variable, char signExponent, int exponent){

node* temp = new node();

temp->sign = sign;
temp->signExponent = signExponent;
temp->exponent = exponent;
temp->variable = variable;
temp->constant = constant;

temp->next = NULL;
current->next = temp;
current = temp;

return current;
}

void printEquation(node* dummy){

// dummy is just an empty node to keep track of front of equation.
// It is not part of equation. Equation starts after dummy node.
node* tmp = dummy->next;

// Print the equation term by term.
while( tmp != NULL ){
printf("%c%d%c^%c%d ", tmp->sign, tmp->constant, tmp->variable, tmp->signExponent, tmp->exponent);
tmp = tmp->next;
}
printf("\n");

}

void calculateEquation(node* dummy, double var){

double sum = 0;
bool calculable;

// dummy->next because dummy node is not a part of the equation.
node* tmp = dummy->next;

while( tmp != NULL ){

double constantValue = 0, variableValue = 0;
calculable = true;

// make constant negative if the sign is negative.
constantValue = tmp->constant;
if(tmp->sign == '-')
constantValue *= -1;

// calculate the value of the variable with given exponent.
variableValue = pow(var, tmp->exponent);
if(tmp->signExponent == '-'){
if(variableValue)
variableValue = (double) 1 / variableValue;
else
calculable = false;
}

// multiply the calculated value of variable with the constant.
sum = sum + variableValue * constantValue;

// calculate the next term of the equation.
tmp = tmp->next;

// If not calculable. Ex: divide by zero. then print this.
if(!calculable){
printf("Sorry Try something different\n");
break;
}

}

// print the result.
if(calculable)
printf(">>\t %f\n", sum);

}

int main(){

// Comment these lines to do I/O operation in console.
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);

char sign;
char signExponent;
int exponent;
char variable;
int constant;

// Dummy node to make insertion code simpler.
node* dummy = new node();
dummy->variable = '\$';
node* current = dummy;

// Take input of equation term by term.
// If
//     taking input from console stop input using null terminator ( ctrl + z ).
// Else
//     when taking input from file enter a 0 in a line by itself to stop input.
while( scanf("%c%d%c%*c%c%d", &sign, &constant, &variable, &signExponent, &exponent ) == 5){
getchar();
current = insertNode(current, sign, constant, variable, signExponent, exponent);
}

// print the
printEquation(dummy);

// Enter different values for the variable to get the value of function.
while(1){
printf("Calculate value of Equation for given value (y/n)?\n");

char choice = getchar();

if( choice == 'y' ){
printf("Enter value for the variable:\n");

double variableValue;
scanf("%lf", &variableValue);
getchar();

calculateEquation(dummy, variableValue);
}else{
printf("Exiting...\n");
break;
}
}

return 0;
}

Ternary Heap Sort Code in C++ using Heap Data structure

Introduction:

This code is implementation of ternary heap sort. The code requires no input. Data inputs (integers) are generated randomly then sorted using heap sort.

Only change the define SIZE value to for sorting large or small amount of numbers.

Code for Binary Heap Sort here.

Ternary Heap Sort Code Cpp:

/**
* @author  Quickgrid ( Asif Ahmed )
* Problem: Ternary Heap Sort
*/

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>

#define SIZE 10
int A[SIZE], heapsize = SIZE;

void maxHeapify(int i){
int largest;

/**
* Find right child index
*/
int l = 3 * i + 1;

/**
* Compare left child against the current node
*/
if(l < heapsize && A[l] > A[i])
largest = l;
else
largest = i;

/**
* find mid child index
*/
int m = 3 * i + 2;

/**
* Compare mid child against the calculated largest value node
*/
if(m < heapsize && A[m] > A[largest])
largest = m;

/**
* Find right child index
*/
int r = 3 * i + 3;

/**
* Compare right child against the calculated largest value node
*/
if(r < heapsize && A[r] > A[largest])
largest = r;

/*
* If child nodes have larger value then current node
*/
if(largest != i){
/**
* Swap the two values
*/
std::swap(A[i], A[largest]);

/**
* Max heapify again rest of the heap
*/
maxHeapify(largest);
}
}

void buildMaxHeap(){
int j;
/**
* operate on third of array
*/
for(j = heapsize / 3 - 1; j >= 0; --j)
maxHeapify(j);
}

void heapsort(){
buildMaxHeap();

int i;
for(i = heapsize - 1; i > 0; --i){
std::swap(A, A[i]);

/**
* Decrease the heap size as right of heap is already sorted
*/
--heapsize;

/**
* Again max heapify the rest of the heap
*/
maxHeapify(0);
}
}

int main(){
int i;

clock_t begin, end;
double time_elapsed;

srand(time(NULL));
for(i=0; i<SIZE; ++i){
A[i] = rand() % SIZE;
printf("%d ", A[i]);
}
printf("\n");

printf("Sorting Now....\n");
begin = clock();
heapsort();
end = clock();

time_elapsed = (double)(end - begin) / CLOCKS_PER_SEC;

for(i=0; i<SIZE; ++i)
printf("%d ", A[i]);

printf("\n\nTime elapsed: %lf\n", time_elapsed);

return 0;
}

UVA Problem 12541 ( Birthdates ) Solution

UVA Problem 12541 ( Birthdates ) Solution:

Click here to go to this problem in uva Online Judge.

Solving Technique:

Rank 363, Run time 9 ms ( 0.009 s ).

This problem seems easy at first glance but requires some thinking. There will be only two output.

First one will be the name of the youngest person ( The person whose was born after everyone ). Meaning his/her birth year, month, date is greater than others. Ex, a person born on 1991 is younger than person born on 1990.

Second one will be the name of the oldest person ( The person whose was born before everyone ). Meaning his/her birth year, month, date is less than others. Ex, a person born on 1990 is older than person born on 1991.

Important:  Be sure to add or print a new line after each output. The outputs should match exactly because sometimes even a space character causes the answer to be marked as wrong answer.

Code Explanation:

Since the name doesn’t exceed 15 letter so an array of size 16 ( i use 1 more for safety ) will suffice. Next there are 4 inputs each time. One is name string, the rest are integers such as date, month and year respectively.

Since the inputs are all related I used a struct to keep all data in a structure named person.

Now I use two more struct variable named young and old. By default I set both of them to first value of our structure. Now I compare if year is greater I set young to that struct variable in that loop. If less than I set old to the struct variable in that loop. If both of these are not true then I follow the same logic for month and date.

In the and the young and old struct variable get set to youngest and oldest struct variable based on logic.

Since I only need to print the youngest and oldest person name so, I just access our young and old structure with name property using dot operator and print them each on a new line.

Input:

10
Machel 31 12 4999
Amar 27 9 1991
Conrad 1 1 1999
Kara 18 9 5001
Tom 29 1 1991
Priyanka 1 12 5001
Melissa 25 10 1991
Ping 16 10 5001
Amidala 10 1 1991
Xena 17 10 5001

Output:

Priyanka
Amidala

Code:

/*
* Author: Quickgrid ( Asif Ahmed )
* Site: https://quickgrid.wordpress.com
* Problem: UVA 12541 ( Birth dates  )
*/

#include<stdio.h>

struct person{
char name;
unsigned int date, month, year;
};

int main(){
register unsigned int n, i = 0;

scanf("%u", &n);

struct person p[n], maxp, minp;

for(; i<n; ++i){
scanf("%s%u%u%u", &p[i].name, &p[i].date, &p[i].month, &p[i].year);
}

maxp = p;    /*younger person*/
minp = p;    /*older person*/

for(i=0; i<n; ++i){
if(p[i].year > maxp.year)
maxp = p[i];

else if(p[i].year < minp.year)
minp = p[i];

else{
if(p[i].month > maxp.month && p[i].year >= maxp.year)
maxp = p[i];

else if(p[i].month < minp.month && p[i].year <= minp.year)
minp = p[i];

else{
if(p[i].date > maxp.date && p[i].month >= maxp.month && p[i].year >= maxp.year)
maxp = p[i];
else if(p[i].date < minp.date && p[i].month <= minp.month && p[i].year <= minp.year)
minp = p[i];
}
}

}

printf("%s\n%s\n", maxp.name, minp.name);

return 0;
}

UVA Problem 591 ( Box of Bricks ) Solution

UVA Problem 591 ( Box of Bricks ) Solution:

Click here to go to this problem in uva Online Judge.

Solving Technique:

If we read this problem carefully then there are a some very important clues,

1. make all stacks the same height (line 2)
2. he sets out to rearrange the bricks, one by one (line 3)
3. The total number of bricks will be divisible by the number of stacks (line 7)

From the above points and problems description it is clear that Little Bob can only move the blocks one by one. Also the first line of input will be less or equal to 50 and the block heights will be less than or equal to 100. So we can use integer ( also unsigned integer ) for them.

Another thing it is said that dividing sum of stack heights with stack count is always possible. Meaning that gives us the height of the wall ( total stacks height sum, h[i] / stack count, n ).

The technique is there can be three types of box stack. That is equal to, less than or greater than height of the wall( total stacks height sum, h[i] / stack count, n ).

Since Bob can move boxes one by one it doesn’t matter which stack to start from. We can find the number of blocks to move from by only subtracting those stack that are greater in height than the max wall height. No need to perform this action on stacks that are equal or less high than max wall height.

So the result is the sum of subtraction of each stacks that are greater than from ( all stack sum / stack count ). Also since blocks are moved one by one this is the final result.

Important:   We normally print a new line after each output line but for this problem asks us to Output a blank line after each set. Meaning with our normal line break we need to add another line break. Be sure to add or print a new line after each output. The outputs should match exactly because sometimes even a space character causes the answer to be marked as wrong answer.

Code Explanation:

1. First I take the stack count and loop that many times. [ also reset moves, and c ( count ) variable each time ]
2. Now for each loop I take the height of stack in an array and sum it.
3. Next I find the wall height by dividing the sum with stack count.
4. Now I use another loop to loop through the array. In it subtract elements greater than stack height and also sum up this value to moves ( number of box movement needed ).
5. Lastly I print in the exact format the problem asked.
6. One more thing I printed an extra newline because the problem asked for a blank line after each set.

Input:

6
5 2 4 1 7 5
0

Output:

Set #1
The minimum number of moves is 5.

Code:

/*
* @author  Quickgrid ( Asif Ahmed )
*/

#include<stdio.h>

static int a;

int main(){
register int i, c = 1;
int n, sum, maxHeight, moves, temp;

while (scanf("%d", &n) && n){
moves = sum = 0;

for (i = 0; i < n; ++i){
scanf("%d", &a[i]);
sum += a[i];
}

maxHeight = sum / n;

for (i = 0; i < n; ++i){
if(a[i] > maxHeight)
moves += a[i] - maxHeight;
}

printf("Set #%d\nThe minimum number of moves is %d.\n\n", c++, moves);
}
return 0;
}

UVA Problem 10324 ( Zeros and Ones ) Solution

UVA Problem 10324 ( Zeros and Ones ) Solution:

Click here to go to this problem in uva Online Judge.

Solving Technique:

Here I have provided naive solution for this problem which is very slow. This code can be solved much much faster. I’ll update to it later.

This One was painful. Got Runtime Error a few times before solving this. Still my best time for this so far is 1.899 sec. My main problem was that it said the problem could end with both an EOF or a new line character. The main problem was new line. So I used getchar() ( found it here one of the best sites for contest programming ) and checked for EOF and string length in the string input while condition.

The problem is quite descriptive. It says our string or character array size can be 1000000The string will contain only ‘0’ and ‘1’ characters. Basically we are to find if the characters between the given interval min(i,j)  and max(i,j)Meaning check for the characters from the minimum number between i or j to the maximum number of i or j.

Important:  Be sure to add or print a new line after each output. The outputs should match exactly because sometimes even a space character causes the answer to be marked as wrong answer.

Code Explanation:

Here the input format is first take a string or character array ( of size 1000000 ) and next take an integer which is the number if inputs to come. Now loop that many times and take two integers ( i and j ) every loop.

I used a flag named works which is set to 1 by default and use this to check condition if the characters match or not.

Now i loop thorough the given interval ( i and jto check if the character in the given interval are same.

In the loop i check every character of the interval string with the first character of that given interval. Since all character need to be same to output is this code is valid.

Now in the loop if any character doesn’t match I set the flag ( works ) to 0, print No since all characters don’t match and break from loop immediately.

Next thing I check if flag is 1 then I print Yes.

Lastly the getchar()

Input:

0000011111
3
0 5
4 2
5 9
01010101010101010101010101111111111111111111111111111111111110000000000000000
5
4 4
25 60
1 3
62 76
24 62
1
1
0 0

Output:

Case 1:
No
Yes
Yes
Case 2:
Yes
Yes
No
Yes
No
Case 3:
Yes

Code Naive Solution ( Slow ):

/**
* Author:  Quickgrid ( Asif Ahmed )
* Site:    https://quickgrid.wordpress.com
* Problem: UVA 10324 - Zeros and Ones
*/

#include<stdio.h>
#include<string.h>

#define N 1000000

static char s[N];

int main(){

int i;
int works, c = 1;
int n, a, b;

while(gets(s)){

scanf("%d", &n);
printf("Case %d:\n", c++);

while( n-- ){

works = 1;

scanf("%d%d",&a,&b);

if(a == b){
printf("Yes\n");
continue;
}

if(a > b){
for(i = b; i <= a; ++i){
if(s[i] != s[a]){
works = 0;
printf("No\n");
break;
}
}
}else{
for(i = a; i <= b; ++i){
if(s[i] != s[a]){
works = 0;
printf("No\n");
break;
}
}
}

if(works)
printf("Yes\n");

}
getchar();
}
return 0;
}

UVA Problem 11192 ( Group Reverse ) Solution

UVA Problem 11192 ( Group Reverse ) Solution:

Click here to go to this problem in uva Online Judge.

Solving Technique:

This one is a bit tricky. Also it seems to be closely related to this ( 483 word scramble ) uva problem. Basically for this problem we are to take an integer ( which is the number of groups ) and a string until we are given a 0. Now our input is given like this,

3 ABCEHSHSH

5 FA0ETASINAHGRI0NATWON0QA0NARI0

0

So, the first problem for beginner is taking input for this. From the input we can easily see that there are two parts and the first part is an integer and second part is a string. Also we need to keep taking input until we find 0. What if we divide our scanf or input taking into two parts. First take the integer and check if its 0 or not then if it’s not zero then take the string and continue like this.

Our first input is an integer which is group number or number of parts the string can be divided to. So, from the given problem statement,

TOBENUMBERONEWEMEETAGAINANDAGAINUNDERBLUEICPCSKY

This string has length 48. We have divided into 8 groups of equal length and so the length of each group is 6. Meaning each group or each part of sentence will consist of 6 characters.

Our task is to reverse print/output each and every group. We can easily find how many members are in each group by dividing the length of the string with input ( number of groups ) we are given.

Important:  Be sure to add or print a new line after each output. The outputs should match exactly because sometimes even a space character causes the answer to be marked as wrong answer.

Code Explanation:

Here I have used stack data structure ( see this and this ) to solve this problem. First I find the length of the string then find how many characters in each group by dividing string length with group number. I also keep a counter ” x “ and keep pushing each character of the string in stack until I reach the last character or until our counter is not equal to the group member count. Also increment the counter each time i push into the stack. Also I keep a condition to check if  I have reach the last character or until our counter is equal to the group member count then pop until our loop counter has reached zero. Since stack is a LIFO data structures the last character i pushed into the stack are the first one to come out ( meaning they are outputted in reverse order ). This process keeps running until we reach the end of the sentence.

Input:

3 ABCEHSHSH
5 FA0ETASINAHGRI0NATWON0QA0NARI0
0

Output:

CBASHEHSH
ATE0AFGHANISTAN0IRAQ0NOW0IRAN0

Commented Code ( See the next Code for easier understanding of stack ):

/**
* @author Quickgrid ( Asif Ahmed )
* @url https://quickgrid.wordpress.com
*/

#include<stdio.h>

/**
* Input string buffer
*/
static char s;

/**
* Global index for accessing input array, may be declared inside main
*/
int top = -1;

int main(){
register unsigned j,u,n,i,x;

/**
* Input group count and Check if count is Not Zero
*/
while (scanf("%u", &n) && n) {
scanf("%s", s);

/**
* Find out input string size
*/
for (j = 0; s[j]; ++j);

/**
* Find out length of each group
*/
n = j / n;

/**
* Group Reverse loop
*/
for (x = i = 0; i < j; ++i) {
/**
* For checking is the item after is NUL terminator
*/
u = s[i + 1];

/**
* @var u
* If the character after current is NUL then NOT u, is True
*
* @var n
* Check to see if characters in group count is NOT full, then push more to stack
*/
if ( !u || x != n ) {
/**
* Push current character on top of stack
*/
s[++top] = s[i];
/**
* Keep a count of characters pushed on stack
*/
++x;
}

/**
* If character limit per group is reached then Condition is True
*/
if ( !u || x == n ) {
/**
* Empty the the stack for every pushed character
*/
while (x--){
/**
* Output character by character in reversed form
*/
printf("%c", s[top]);
--top;
}
x = 0;
}

}
printf("\n");
}
return 0;
}

Code:

/*
* Author: Quickgrid ( Asif Ahmed )
* Site: https://quickgrid.wordpress.com
*/

#include<stdio.h>

char s;
int top = -1;

void push(char c){
if(top + 1 >= 101)
return;

s[++top] = c;
}

void pop(){
if (top == -1)
return;

printf("%c", s[top]);
s[top--] = '\0';
}

int main(){
int n,j,i,x;
while (scanf("%d", &n) == 1 && n != 0){
x = 0;
scanf("%s", &s);
for (i = 0; s[i]; ++i);
n = i / n;

for (i = 0; s[i]; ++i){
if (s[i+1] == '\0' || x != n){
push(s[i]);
++x;
}

if (s[i+1] == '\0' || x == n){
while (x--)
pop();

x = 0;
}
}

printf("\n");
}
return 0;
}