336 – A Node Too Far UVA Solution

This is an easy problem from uva judge http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=272

Graphs, Breadth First Search. Single Source Shortest Path.

How I did it

  • I read the number of edges while edges != 0.
  • Read the graph.
  • Read the node to search and the ttl while node !=0 and ttl != 0.
  • Call bfs(node) and init notReach = 0.
  • Traverse all the calculated distance from node. If  (distance > ttl) notReach+1;
  • Traverse the visited map. If an node is not visited. notReach+1.
  • Print notReach.

Hints

  • The nodes doesnot follow a correlative order.
  • Carefull with the nodes that are not connected in the bfs request.(check my case)

Input

4
0 2
1 0
1 3
4 5
0 2
4 100
0 0
0

Output

Case 1: 4 nodes not reachable from node 4 with TTL = 100.

Code

#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
#define MAXN    500

using namespace std;

map <int, vector <int> > graph;
map<int,bool> discovered;//keeps track if a node has been reached
map<int,int>  parent;//stores the nodes ancestor that discovered it for the first time
map<int,int>  distances;//stores the distance to reach each node from the source

void read_graph(int edges)
{
    graph.clear();
    int vertex1,  vertex2;
    int i;
    for(i = 0; i < edges; i++)
    {
        scanf("%d %d", &vertex1, &vertex2);
        graph[vertex1].push_back(vertex2);
        graph[vertex2].push_back(vertex1);

        discovered[vertex1] = false;discovered[vertex2] = false;
        parent[vertex1] = -1;parent[vertex2] = -1;
        distances[vertex1] = -1;distances[vertex2] = -1;
    }
}

void clearGraph()
{
    for(map<int,int>::iterator iter = distances.begin(); iter != distances.end(); iter++)
        distances[iter->first] = -1;
    for(map<int,int>::iterator iter = parent.begin(); iter != parent.end(); iter++)
        parent[iter->first] = -1;
    for(map<int,bool>::iterator iter = discovered.begin(); iter != discovered.end(); iter++)
        discovered[iter->first] = false;
}

void bfs(int start)
{
    int current;//current node being processed
    int next;//reached node by current
    unsigned int i;
    queue<int> vertices;//vertices to process
    distances[start] = 0;
    discovered[start] = true;
    vertices.push(start);
    while(!vertices.empty())
    {
        current = vertices.front();
        vertices.pop();
        for(i = 0; i < graph[current].size(); i++)//for each node connected to current
        {
            next = graph[current][i];
            if(!discovered[next])//if it hasn't been reached
            {
                discovered[next] = true;//mark it as reached
                parent[next] = current;//store its parent
                distances[next] = distances[current]+1;//save the distance
                vertices.push(next);//push it to the queue for further analysis
            }
        }
    }
}

/*void find_path(int vertex)//recursive procedure to find the path
{
    if(vertex == -1)
        return;
    find_path(parent[vertex]);
    printf("%d ", vertex);
}*/

int main()
{
    int vertices, edges, start, ttl, notReach, casos = 1;
    while(scanf("%d", &edges))
    {
        if(!edges)
           break;
        read_graph(edges);

        while(scanf("%d %d", &start, &ttl))
        {
            if(!start && !ttl)
               break;

            bfs(start);
            notReach = 0;
            for(map<int,int>::iterator it = distances.begin(); it!= distances.end(); it++)
                if(it->second > ttl)
                   notReach++;

            for(map<int,bool>::iterator it = discovered.begin(); it!= discovered.end(); it++)
                if(it->second == false)
                   notReach++;

            printf("Case %d: %d nodes not reachable from node %d with TTL = %d.\n",casos++, notReach,start, ttl);
            clearGraph();
        }
        discovered.clear();//keeps track if a node has been reached
        parent.clear();//stores the nodes ancestor that discovered it for the first time
        distances.clear();//stores the distance to reach each node from the source
    }
return 0;
}

11953 – Battleships UVA Solution

This is an easy problem from uva judge http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=3104

Implicit graph, connected components.

How I did it

  • I read the number of cases.
  • Read the row size.
  • Read the matrix. If a cell is equal to ‘@’ or ‘x’ set dfs_matriz cell with -1 (Not visited). Otherwise with 0.
  • Traverse all the matrix.
  • If a potencial node is founded and not visited yet  call dfs(row, col).
  • If one element in the current dfs traversal is equal to ‘x’. I found a ship, so increment the number of ships.
  • Print the number of ships.

Hints

  • x@x . Is just a ship
  • The input is really small.

Code

#include <iostream>
#include <cstdio>
#define MAX 101
#define DFS_WHITE -1
#define DFS_BLACK 1
using namespace std;
int matriz[MAX][MAX], dfs_matriz[MAX][MAX], grid;
bool flag;

void initGraph()
{
string str = "", tmp;
    for(int a=0; a<grid; a++)
    {
        cin>>tmp;
        str+=tmp;
    }

    int index = 0;
    for(int x=0; x<grid; x++)
        for(int y=0; y<grid; y++,index++)
        {
            matriz[x][y] = str[index];
            if(matriz[x][y] == 'x' || matriz[x][y] == '@')
                dfs_matriz[x][y] = DFS_WHITE;
            else
                dfs_matriz[x][y] = 0;
        }
}

void dfs(int x, int y)
{
    if(matriz[x][y] == 'x')
       flag = true;
    dfs_matriz[x][y] = DFS_BLACK;
    int a=x, b=y;
            if(a-1 >= 0)
            {
                if(dfs_matriz[a-1][b] == DFS_WHITE)
                    dfs(a-1, b);
            }
            if(a+1 < grid)
            {
                if(dfs_matriz[a+1][b] == DFS_WHITE)
                    dfs(a+1, b);
            }
            if(b-1 >= 0 && dfs_matriz[a][b-1] == DFS_WHITE)
                dfs(a,b-1);
            if(b+1 < grid && dfs_matriz[a][b+1] == DFS_WHITE)
                dfs(a,b+1);
}

int main()
{
int casos, ships;
scanf("%d", &casos);

for(int a=1; a<=casos; a++)
{
    scanf("%d", &grid);
    initGraph();
    ships = 0;

    for(int x=0; x<grid; x++)
        for(int y=0; y<grid; y++)
        {
            if( (matriz[x][y] == 'x' || matriz[x][y] == '@') && dfs_matriz[x][y] == DFS_WHITE)
            {
                flag = false;
                dfs(x,y);
                if(flag == true)
                   ships++;
            }
        }
    printf("Case %d: %d\n",a ,ships);
}

return 0;
}

11470 – Square Sums UVA Solution

This is an easy problem from uva judge http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=2465

Grpah traversal, implicit graph.

How I did it

  • I read the size of a row and column .
  • Read the graph.
  • Init left = 0 and rigth =  row size -1;
  • While left <= rigth traverse the matrix and find the value of the concentric squares.
  • Save the result inside a vector.
  • Print the graph.

Hints

  • A concentric square form a  graph .
  • The input is really small 10 x 10 max size. So im using just brute force with many traversal.

Input

5

5 3 2 7 9
1 7 4 2 4
5 3 2 4 6
1 3 4 5 1
1 4 5 6 3

6

5 3 2 7 9 1
1 7 4 2 4 1
5 3 2 4 6 1
1 3 4 5 1 1
1 4 5 6 3 1
1 1 1 1 1 1

1

1

6

1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1

0

Output

Case #1: 63 32 2
Case #2: 45 48 15
Case #3: 1
Case #4: 20 12 4

Code

#include <iostream>
#include <cstdio>
#include <vector>
#define NODES 11
#define DFS_WHITE -1
#define DFS_BLACK 1
using namespace std;

int matriz[NODES][NODES], dfs_matriz[NODES][NODES];
int graphSize, total=0, caso=1;

void initGraph(int row)
{
    for(int x=0; x<row; x++)
        for(int y=0; y<row; y++)
        {
            scanf("%d", &matriz[x][y]);
            dfs_matriz[x][y] = DFS_WHITE;
        }
}

int main()
{

while(scanf("%d", &graphSize))
{
    if(!graphSize)
       break;
    initGraph(graphSize);
    int left = 0, right = graphSize - 1;
    vector<int> vec;
    while(left <= right)
    {
        for(int x=0; x<graphSize; x++)
        {
            for(int y=0; y<graphSize; y++)
            {
                if( (x == left || y == left || x == right || y == right) && dfs_matriz[x][y] == DFS_WHITE)
                {
                    total += matriz[x][y];
                    dfs_matriz[x][y] = DFS_BLACK;
                }
            }
        }
        vec.push_back(total);
        total = 0;
        left++;
        right--;
    }
    printf("Case %d: ",caso++);
    for(int a=0; a<vec.size(); a++)
    {
        if(a < vec.size() - 1)
           printf("%d ", vec[a]);
        else
            printf("%d\n", vec[a]);
    }
    vec.clear();
}

return 0;
}

11219 – How old are you? UVA Solution

This is an easy problem from uva judge http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=2160

A really easy problem. Input parsing, Ad hoc.

How I did it

  • I read the number of cases .
  • Read the current date and parse the data. (scanf)
  • Read the birth date and parse the data. (scanf)
  • If the person still to be born, print “Invalid birthdate”.
  • Otherwise if the person has more than 130 year, print “Check the date”.
  • Otherwise print the age of the person.

Hints

  • Parse the date is really easy with scanf –>>> scanf(“%d/%d/%d”, &cd, &cm, &cy).
  • Be carefull checking the age of the person. I do this (First check year, after that month, after that day).

Code

#include <iostream>
#include <cstdio>
using namespace std;
int  cd,cm,cy, bd,bm, by, age;

bool checkInvalid()
{
    if(cy < by)
       return true;
    else if(cy == by)
    {
        if(cm < bm)
           return true;
        else if(cm == bm)
        {
            if(cd < bd)
               return true;
            else
                return false;
        }
        else
            return false;
    }
    else
        return false;
}

bool checkBirth()
{
age = cy - by;
    if(cm < bm)
       age--;
    else if(cm == bm)
            if(cd < bd)
               age--;
    if(age > 130)
       return true;
    else
        return false;
}

int main()
{
int casos;

scanf("%d", &casos);
for(int x=1; x<=casos; x++)
{
    scanf("%d/%d/%d", &cd, &cm, &cy);
    scanf("%d/%d/%d", &bd, &bm, &by);

    if(checkInvalid())
       printf("Case #%d: Invalid birth date\n", x);
    else if(checkBirth())
            printf("Case #%d: Check birth date\n", x);
    else
        printf("Case #%d: %d\n", x, age);
}
return 0;
}

12555 – Baby Me UVA Solution

This is an easy problem from uva judge http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=4000

A really easy problem. Input parsing, output formatting.

How I did it

  • I read the number of cases .
  • Read the string with the current case.
  • Get the first and second number.
  • Get the result (num1 * 0.5) + (num2 * 0.05).
  • Print the result with cout.

Hints

  • You need to print the most accurate result posible.
  • Cout rounds the double numbers instead of printf(). I love printf(), but in this case cout is more useful.

Code

#include <iostream>
#include <cstdio>
#include <cctype>
#include <cmath>
using namespace std;

int parseInt(string str)
{
    int res;
    for(int z=0; z<str.size(); z++)
    {
        if(z == 0)
           res = str[z] - '0';
        else
            res = (res * 10) + (str[z] - '0');
    }
return res;
}

int main()
{
string str, n1, n2;
int casos, num1, num2;
bool flag;

scanf("%d", &casos);
for(int l=1; l<=casos; l++)
{
    flag = false;
    n1 = n2 = "";
    cin>>str;
    for(int z=0; z<str.size(); z++)
    {
        if(isdigit(str[z]) && !flag)
           n1 += str[z];
        else if(!isdigit(str[z]))
            flag = true;
        else
            n2 += str[z];
    }

    num1 = parseInt(n1);
    if(n2.size() == 0)
       num2 = 0;
    else
        num2 = parseInt(n2);

    double result = (num1 * 0.5) + (num2 * 0.05);
    cout<<"Case "<<l<<": "<<result<<"\n";
}
return 0;
}