20131224

[資結] Expression Tree

















答案是14

說明
輸入給予下列資訊:
第一行會給定一個整數n,代表節點的個數。 n 最多不超過100,000。
接下來會有 n 行,每一行代表一個節點的資訊,其內容如下:
第一個數字代表節點的ID,分別是1~n不重複(不一定照順序)。
接下來會有一個字串,可能會是SUM, MIN, MAX, VAL 四種其中之一,分別代表總和、最小值、最大值、或是Leaf node。
接下來會是一個數字,代表此節點的parent ID。
如果這個節點是Leaf node (即第二個字串是VAL),該行最後會有一個數字代表此節點的值。
(parent 是 -1 表示該node是root)
output用%d即可。

input
13
1 SUM 2
2 MAX -1
3 SUM 2
4 MAX 3
5 VAL 1 3
6 MIN 1
7 VAL 1 2
8 VAL 3 6
9 VAL 6 4
10 VAL 6 2
11 VAL 4 5
12 VAL 4 3
13 VAL 4 8

output
14

解法:
因為不是binary tree。
所以做left child right sibling。
再做traverse即可。

太久沒寫tree,我的指標又在飄了 lol~

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

#define MAXNODE 100001

typedef struct node {
    char data[4];
    int value;
    struct node *left;
    struct node *right;
} Node;

void init(Node *nodes, int n);
void addchild(Node *node, Node *child);
int traverse(Node *node);
int sum(Node *node);
int max(Node *node);
int min(Node *node);

int main(void)
{
    int n, i, p, root, index;
    Node nodes[MAXNODE];

    scanf("%d", &n);
    init(nodes, n);
    for (i = 0; i < n; i++) {
        // input
        scanf("%d", &index);
        scanf("%s %d", nodes[index].data, &p);
        if (strcmp(nodes[index].data, "VAL") == 0) {
            scanf("%d", &nodes[index].value);
        }

        if (p == -1)
            root = index;
        else
            addchild(&nodes[p], &nodes[index]);
    }
    printf("%d\n", traverse(&nodes[root]));

    return 0;
}

void init(Node *nodes, int n)
{
    int i;
    for (i = 1; i <= n; i++) {
        nodes[i].left = nodes[i].right = NULL;
    }
}

void addchild(Node *node, Node *child)
{
    if (node->left == NULL) {
        node->left = child;
        return;
    }
    else
        node = node->left;
    while (node->right != NULL)
        node = node->right;
    node->right = child;
}

int traverse(Node *node)
{
    // no child is leaf
    if (node->left == NULL) {
        return node->value;
    }

    if (strcmp(node->data, "SUM") == 0) {
        return sum(node->left);
    }
    else if (strcmp(node->data, "MAX") == 0) {
        return max(node->left);
    }
    else if (strcmp(node->data, "MIN") == 0) {
        return min(node->left);
    }
}

int sum(Node *node)
{
    int sum = traverse(node);

    while (node->right != NULL) {
        sum += traverse(node->right);
        node = node->right;
    }
    return sum;
}

int max(Node *node)
{
    int max = traverse(node);
    int temp;

    while (node->right != NULL) {
        temp = traverse(node->right);
        if (max < temp)
            max = temp;
        node = node->right;
    }
    return max;
}

int min(Node *node)
{
    int min = traverse(node);
    int temp;

    while (node->right != NULL) {
        temp = traverse(node->right);
        if (min > temp)
            min = temp;
        node = node->right;
    }
    return min;
}

20120404

ACM 10074 Take the Land

ACM836
1跟0要互轉。

/* ACM 10074 Take the Land
 * mythnc
 * 2012/04/04 17:16:52
 * run time: 0.012
 */
#include <stdio.h>
#include <string.h>

#define MAXN 100

void input(int (*)[]);
int findsubsum(int (*)[]);
int subsum(int *, int *, int);

int maxrow, maxcol;

int main(void)
{
    int matrix[MAXN][MAXN];

    while (scanf("%d %d", &maxrow, &maxcol) && maxrow != 0) {
        input(matrix);
        printf("%d\n", findsubsum(matrix));
    }

    return 0;
}

/* input: receive input data. */
void input(int (*matrix)[MAXN])
{
    int i, j, tmp;

    for (i = 0; i < maxrow; i++)
        for (j = 0; j < maxcol; j++) {
            scanf("%d", &tmp);
            /* exchange 0 and 1 */
            if (tmp == 1)
                matrix[i][j] = 0;
            else
                matrix[i][j] = 1;
        }
}

/* findsubsum: find sub sum and return it */
int findsubsum(int (*matrix)[MAXN])
{
    int max, sum, i, j;
    int line[MAXN];

    /* from row 1 to N, 2 to N, ... , calculate each
     * subsum */
    for (i = max = 0; i < maxrow; i++) {
        /* init line */
        memset(line, 0, sizeof(int) * maxcol);
        for (j = i; j < maxrow; j++) {
            sum = subsum(line, matrix[j], j - i + 1);
            if (max < sum)
                max = sum;
        }
    }

    return max;
}

/* subsum: use Kadane's algorithm to find the subsum */
int subsum(int *line, int *matrix, int rown)
{
    int i, sum, max;
    /* add each column to line */
    for (i = 0; i < maxcol; i++)
        line[i] += matrix[i];

    for (i = sum = max = 0; i < maxcol; i++) {
        if (line[i] != rown) {
            sum = 0;
            continue;
        }
        sum += line[i];
        if (sum > max)
            max = sum;
    }

    return max;
}

20120403

ACM 836 Largest Submatrix

Maximum Sum。同ACM108
因為只有1跟0,所以n個row的和,最大值必為n。
只要判斷該field的值是否是n,
就能判斷Maximum Sum。

/* ACM 836 Largest Submatrix
 * mythnc
 * 2012/04/03 16:01:37   
 * run time: 0.004
 */
#include <stdio.h>
#include <string.h>

#define MAXN 25

int input(char (*)[]);
int findsubsum(char (*)[], int);
int subsum(int *, char *, int, int);
void ctoi(int *, char *, int);

int main(void)
{
    int n, i, len;
    char matrix[MAXN][MAXN + 1];

    scanf("%d", &n);
    /* eat '\n' */
    getchar();
    for (i = 0; i < n; i++) {
        if (i > 0)
            putchar('\n');
        /* eat blank line */
        getchar();
        len = input(matrix);
        printf("%d\n", findsubsum(matrix, len));
    }

    return 0;
}

/* input: receive input data.
 * return its len */
int input(char (*matrix)[MAXN])
{
    int len, i;

    scanf("%s", matrix[0]);
    len = strlen(matrix[0]);
    for (i = 1; i < len; i++)
        scanf("%s", matrix[i]);

    return len;
}

/* findsubsum: find sub sum and return it */
int findsubsum(char (*matrix)[MAXN], int len)
{
    int max, sum, i, j;
    int line[MAXN];

    /* from row 1 to N, 2 to N, ... , calculate each
     * subsum */
    for (i = max = 0; i < len; i++) {
        /* init line */
        memset(line, 0, sizeof(int) * len);
        for (j = i; j < len; j++) {
            sum = subsum(line, matrix[j], len, j - i + 1);
            if (max < sum)
                max = sum;
        }
    }

    return max;
}

/* subsum: use Kadane's algorithm to find the subsum */
int subsum(int *line, char *row, int len, int rown)
{
    int i, sum, max;

    /* add row to line */
    ctoi(line, row, len);

    for (i = sum = max = 0; i < len; i++) {
        if (line[i] != rown) {
            sum = 0;
            continue;
        }
        sum += line[i];
        if (sum > max)
            max = sum;
    }

    return max;
}

/* ctoi: transform char to int */
void ctoi(int *line, char *row, int len)
{
    int i;

    for (i = 0; i < len; i++)
        line[i] += row[i] - '0';
}

20120118

ACM 507 Jill Rides Again

maximum sum problem。
一樣用kadane去解。
不過不太一樣的是要注意sum == max的情況,
要找最大範圍的起始點 + 終點。

/* ACM 507 Jill Rides Again
 * mythnc
 * 2012/01/18 11:15:29   
 * run time: 0.136
 */
#include <stdio.h>

#define MAXS 20001

void input(void);
void kadane(void);
void output(int);

int list[MAXS];
int n, maxstart, maxend;

int main(void)
{
    int set, i;

    scanf("%d", &set);
    for (i = 1; i <= set; i++) {
        input();
        kadane();
        output(i);
    }

    return 0;
}

/* input: receive input data */
void input(void)
{
    int i;

    scanf("%d", &n);
    for (i = 1; i < n; i++)
        scanf("%d", &list[i]);
}

/* kadane: use kadane algorithm to find the maximum sum */
void kadane(void)
{
    int max, start, end;
    int sum;

    max = 0;
    maxstart = maxend = sum = 0;
    start = 1;
    for (end = 1; end < n; end++) {
        sum += list[end];
        if (sum > max) {
            max = sum;
            maxstart = start;
            maxend = end;
        }
        else if (sum == max && end - start > maxend - maxstart) {
            maxstart = start;
            maxend = end;
        }
        if (sum < 0) {
            sum = 0;
            start = end + 1;
        }
    }
}

/* output: out put result */
void output(int set)
{
    if (maxstart == 0)
        printf("Route %d has no nice parts\n", set);
    else
        printf("The nicest part of route %d is between stops %d and %d\n",
               set, maxstart, maxend + 1);
}

20120117

ACM 11137 Ingenuous Cubrency

DP。
ACM674

/* ACM 11137 Ingenuous Cubrency
 * mythnc
 * 2012/01/17 21:40:44   
 * run time: 0.032
 */
#include <stdio.h>

#define MAXN 10000
#define MAXC 21

int main(void)
{
    int coin[MAXC] = {1, 8, 27, 64, 125, 216,
                    343, 512, 729, 1000, 1331, 1728,
                    2197, 2744, 3375, 4096, 4913, 5832,
                    6859, 8000, 9261};
    long long dp[MAXN] = { 1 };
    int i, j, money;

    for (i = 0; i < MAXC; i++)
        for (j = coin[i]; j < MAXN; j++)
            dp[j] += dp[j - coin[i]];

    while (scanf("%d", &money) == 1)
        printf("%lld\n", dp[money]);

    return 0;
}