Saturday, August 28, 2010

poj_1664_放苹果.cpp

Problem Links:


poj1664,

Problem:


放苹果
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 16665
Accepted: 10512
Description
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
Input
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
Output
对输入的每组数据M和N,用一行输出相应的K。
Sample Input
1
7 3
Sample Output
8
Source
lwx@POJ

poj_1611_The_Suspects.cpp

Problem Links:

Poj1611, Zoj1789,

Problem:

The Suspects
Time Limit: 1000MS
Memory Limit: 20000K
Total Submissions: 10142
Accepted: 4839
Description
Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized as a global threat in mid-March 2003. To minimize transmission to others, the best strategy is to separate the suspects from others.
In the Not-Spreading-Your-Sickness University (NSYSU), there are many student groups. Students in the same group intercommunicate with each other frequently, and a student may join several groups. To prevent the possible transmissions of SARS, the NSYSU collects the member lists of all student groups, and makes the following rule in their standard operation procedure (SOP).
Once a member in a group is a suspect, all members in the group are suspects.
However, they find that it is not easy to identify all the suspects when a student is recognized as a suspect. Your job is to write a program which finds all the suspects.
Input
The input file contains several cases. Each test case begins with two integers n and m in a line, where n is the number of students, and m is the number of groups. You may assume that 0 < n <= 30000 and 0 <= m <= 500. Every student is numbered by a unique integer between 0 and n−1, and initially student 0 is recognized as a suspect in all the cases. This line is followed by m member lists of the groups, one line per group. Each line begins with an integer k by itself representing the number of members in the group. Following the number of members, there are k integers representing the students in this group. All the integers in a line are separated by at least one space.
A case with n = 0 and m = 0 indicates the end of the input, and need not be processed.
Output
For each case, output the number of suspects in one line.
Sample Input
100 4
2 1 2
5 10 13 11 12 14
2 0 1
2 99 2
200 2
1 5
5 1 2 3 4 5
1 0
0 0
Sample Output
4
1
1
Source
Asia Kaohsiung 2003

Solution:


Disjoint set data structure, using find-union algorithms.

Source Code:

//Fri Jun  4 01:13:00 EDT 2010
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define MMAX 30001
using namespace std;

class Suspects
{
public:
    int parent; //The number of element in the union at root, else it's the parent's number;
};

vector<Suspects> v(MMAX);

void MakeSet(int N)
{
    for (int i = 0; i < N; i++)
    {
        v[i].parent = -1;
    }
}

int Find(int x)
{
    int p = x;
    while (v[p].parent > 0)
        p = v[p].parent;
    while (x != p)
    {
        int temp = v[x].parent;
        v[x].parent = p;
        x = temp;
    }
    return p;
}

void Union(int x, int y)
{
    int t1 = Find(x);
    int t2 = Find(y);
    if (t1 == t2)
        return;
    if (v[t1].parent >= v[t2].parent)
    {
        v[t2].parent += v[t1].parent;
        v[t1].parent = t2;
    }
    else
    {
        v[t1].parent += v[t2].parent;
        v[t2].parent = t1;
    }
}

int main(int argc, const char* argv[])
{
    //  freopen("input.in", "r", stdin);
    //  freopen("output.out", "w", stdout);
    int M, N;
    while ((cin >> N >> M) && (M + N))
    {
        MakeSet(N);
        for (int i = 0; i < M; i++)
        {
            int k, num;
            cin >> k >> num;
            Union(num, num);
            for (int j = 1; j < k; j++)
            {
                int temp;
                cin >> temp;
                Union(num, temp);
            }
        }
        cout << -v[Find(0)].parent << endl;
    }
    //  fclose(stdin);
    //  fclose(stdout);
    return 0;
}

poj_1590_Palindromes.cpp

Problem Links:

poj1590, uva00401,

Problem:

Palindromes
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 2480
Accepted: 886
Description
A regular palindrome is a string of numbers or letters that is the same forward as backward. For example, the string "ABCDEDCBA" is a palindrome because it is the same when the string is read from left to right as when the string is read from right to left.

A mirrored string is a string for which when each of the elements of the string is changed to its reverse (if it has a reverse) and the string is read backwards the result is the same as the original string. For example, the string "3AIAE" is a mirrored string because "A" and "I" are their own reverses, and "3" and "E" are each others' reverses.


A mirrored palindrome is a string that meets the criteria of a regular palindrome and the criteria of a mirrored string. The string "ATOYOTA" is a mirrored palindrome because if the string is read backwards, the string is the same as the original and because if each of the characters is replaced by its reverse and the result is read backwards, the result is the same as the original string. Of course, "A", "T", "O", and "Y" are all their own reverses.

A list of all valid characters and their reverses is as follows.
Character  Reverse  Character  Reverse  Character  Reverse  

    A         A         M         M         Y         Y

    B                   N                   Z         5

    C                   O         O         1         1

    D                   P                   2         S

    E         3         Q                   3         E

    F                   R                   4

    G                   S         2         5         Z

    H         H         T         T         6

    I         I         U         U         7

    J         L         V         V         8         8

    K                   W         W         9

    L         J         X         X

Note that O (zero) and 0 (the letter) are considered the same character and therefore ONLY the letter "0" is a valid character.
Input
Input consists of strings (one per line) each of which will consist of one to twenty valid characters. There will be no invalid characters in any of the strings. Your program should read to the end of file.
Output
For each input string, you should print the string starting in column 1 immediately followed by exactly one of the following strings.

" -- is not a palindrome."
if the string is not a palindrome and is not a mirrored string

" -- is a regular palindrome."
if the string is a palindrome and is not a mirrored string

" -- is a mirrored string."
if the string is not a palindrome and is a mirrored string

" -- is a mirrored palindrome."
if the string is a palindrome and is a mirrored string


Note that the output line is to include the -'s and spacing exactly as shown in the table above and demonstrated in the Sample Output below.

In addition, after each output line, you must print an empty line.
Sample Input
NOTAPALINDROME 
ISAPALINILAPASI 
2A3MEAS 
ATOYOTA
Sample Output
NOTAPALINDROME -- is not a palindrome.

ISAPALINILAPASI -- is a regular palindrome.

2A3MEAS -- is a mirrored string.

ATOYOTA -- is a mirrored palindrome.
Source
South Central USA 1995

Solution:

Straight forward, write every condition as one function.
and then use the combination of the functions to tell which belongs to which.

Source Code:

//Mon Mar  8 15:51:39 CST 2010
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;

char mirroredChar(char a)
{
    switch (a)
    {
    case 'A':
        return 'A';
    case 'E':
        return '3';
    case 'H':
        return 'H';
    case 'I':
        return 'I';
    case 'J':
        return 'L';
    case 'L':
        return 'J';
    case 'M':
        return 'M';
    case 'O':
        return 'O';
    case 'S':
        return '2';
    case 'T':
        return 'T';
    case 'U':
        return 'U';
    case 'V':
        return 'V';
    case 'W':
        return 'W';
    case 'X':
        return 'X';
    case 'Y':
        return 'Y';
    case 'Z':
        return '5';
    case '1':
        return '1';
    case '2':
        return 'S';
    case '3':
        return 'E';
    case '5':
        return 'Z';
    case '8':
        return '8';
    default:
        return '*';
    }
}

bool isPalindrome(string str)
{
    string ss = str;
    reverse(ss.begin(), ss.end());
    if (ss == str)
        return true;
    return false;
}

bool isMirrored(string str)
{
    string ss = str;
    for (int i = 0; i < ss.size(); i++)
    {
        ss[i] = mirroredChar(ss[i]);
    }
    reverse(ss.begin(), ss.end());
    if(ss == str) return true;
    return false;
}

int main(int argc, const char* argv[])
{
//  freopen("input.txt", "r", stdin);
//  freopen("output.txt", "w", stdout);
    string str;
    while (cin >> str)
    {
        bool flag1 = isPalindrome(str);
        bool flag2 = isMirrored(str);
        if (!flag1 && !flag2)
            cout << str << " -- is not a palindrome." << endl;
        else if (flag1 && !flag2)
            cout << str << " -- is a regular palindrome." << endl;
        else if (!flag1 && flag2)
            cout << str << " -- is a mirrored string." << endl;
        else
            cout << str << " -- is a mirrored palindrome." << endl;
        cout << endl;
    }
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

UVa_00414_Machined_Surfaces.cpp

Problem Links:


poj1493, uva00414,

Problem:

Machined Surfaces
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 1235
Accepted: 837
Description
An imaging device furnishes digital images of two machined surfaces that eventually will be assembled in contact with each other. The roughness of this final contact is to be estimated.


A digital image is composed of the two characters, "X" and " " (space). There are always 25 columns to an image, but the number of rows, N, is variable. Column one (1) will always have an "X" in it and will be part of the left surface. The left surface can extend to the right from column one (1) as contiguous X's.


Similarly, column 25 will always have an "X" in it and will be part of the right surface. The right surface can extend to the left from column 25 as contiguous X's.

Digital-Image View of Surfaces
   Left                               Right



   XXXX                                      XXXXX  ←1

   XXX                                     XXXXXXX

   XXXXX                                      XXXX

   XX                                       XXXXXX

   .                                             .

   .                                             .

   .                                             .

   XXXX                                       XXXX

   XXX                                       XXXXX  ←N

  ↑                             ↑

  1               25

In each row of the image, there can be zero or more space characters separating the left surface from the right surface. There will never be more than a single blank region in any row.

For each image given, you are to determine the total ``void" that will exist after the left surface has been brought into contact with the right surface. The ``void" is the total count of the spaces that remains between the left and right surfaces after theyhave been brought into contact.

The two surfaces are brought into contact by displacing them strictly horizontally towards each other until a rightmost "X" of the left surface of some row is immediately to the left of the leftmost "X" of the right surface of that row. There is no rotation or twisting of these two surfaces as they are brought into contact; they remain rigid, and only move horizontally.

Note: The original image may show the two surfaces already in contact, in which case no displacement enters into the contact roughness estimation.
Input
The input consists of a series of digital images. Each image data set has the following format:

First line -
A single unsigned integer, N, with value greater than zero (0) and less than 13. The first digit of N will be the first character on a line.

Next N lines -
Each line has exactly 25 characters; one or more X's, then zero or more spaces, then one or more X's.

The end of data is signaled by a null data set having a zero on the first line of an image data set and no further data.
Output
For each image you receive as a data set, you are to reply with the total void (count of spaces remaining after the surfaces are brought into contact). Use the default output for a single integer on a line.
Sample Input
4
XXXX                XXXXX
XXX               XXXXXXX
XXXXX                XXXX
XX                 XXXXXX
2
XXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXX
1
XXXXXXXXX              XX
0
Sample Output
4
0
0
Source
East Central North America 1995

Solution:


Just Simulation;

Source Code:

//Tue Mar  9 02:04:56 CST 2010
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;

int main(int argc, const char* argv[])
{
//  freopen("input.txt", "r", stdin);
//  freopen("output.txt", "w", stdout);
    int n;
    while (cin >> n && n != 0)
    {
        string str;
        int count = 0;
        int localMin = -1;
        for (int i = 0; i < n; i++)
        {
            getchar();
            int cnt = 0;
            getline(cin, str);
            for (int idx = 0; idx < (int) str.size(); idx++)
                cnt += (str[idx] == ' ' ? 1 : 0);
            count += cnt;
            localMin = (localMin > cnt || localMin == -1 ? cnt : localMin);
        }
        cout << count - n * localMin << endl;
    }
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

poj_1477_BoxofBricks.cpp

Problem Links:


poj1477,

Problem:

Box of Bricks
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 10673
Accepted: 4651
Description
Little Bob likes playing with his box of bricks. He puts the bricks one upon another and builds stacks of different height. "Look, I've built a wall!", he tells his older sister Alice. "Nah, you should make all stacks the same height. Then you would have a real wall.", she retorts. After a little con- sideration, Bob sees that she is right. So he sets out to rearrange the bricks, one by one, such that all stacks are the same height afterwards. But since Bob is lazy he wants to do this with the minimum number of bricks moved. Can you help?


poj_1471_Triangles.cpp

Problem Links:

Zoj1245, Poj1471, UVa00585,

Problem:

Triangles
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 1472
Accepted: 530
Description
It is always very nice to have little brothers or sisters. You can tease them, lock them in the bathroom or put red hot chili in their sandwiches. But there is also a time when all meanness comes back!

As you know, in one month it is Christmas and this year you are honored to make the big star that will be stuck on the top of the Christmas tree. But when you get the triangle-patterned silver paper you realize that there are many holes in it. Your little sister has already cut out smaller triangles for the normal Christmas stars. Your only chance is to find an algorithm that tells you for each piece of silver paper the size of the largest remaining triangle.

poj_1458_Common_Subsequence.cpp

Problem Links:

poj1458,

Problem:

Common Subsequence
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 22340
Accepted: 8524
Description
A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = < x1, x2, ..., xm > another sequence Z = < z1, z2, ..., zk > is a subsequence of X if there exists a strictly increasing sequence < i1, i2, ..., ik > of indices of X such that for all j = 1,2,...,k, xij = zj. For example, Z = < a, b, f, c > is a subsequence of X = < a, b, c, f, b, c > with index sequence < 1, 2, 4, 6 >. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y.
Input
The program input is from the std input. Each data set in the input contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct.
Output
For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.
Sample Input
abcfbc         abfcab
programming    contest 
abcd           mnp
Sample Output
4
2
0
Source
Southeastern Europe 2003

Solution:


Basically, it's a straight forward dynamic programming problem----longest common subsequence.
It's pretty much like POJ1159, I used the same subfunction to get the answer.

Source Code:

//Tue Apr 13 15:46:54 CDT 2010
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;

int LongestIncreasingCommonSubsequence(string A, string B)
{
    int N = A.size();
    int M = B.size();
    vector<vector<int> > v(N + 1, vector<int>(M + 1, 0));
    for (int i = 0; i <= N; i++)
    {
        for (int j = 0; j <= M; j++)
        {
            if (i == 0 || j == 0)
                v[i][j] = 0;
            else if(A[i-1] == B[j-1])
                v[i][j] = v[i-1][j-1] + 1;
            else
                v[i][j] = max(v[i-1][j], v[i][j-1]);
        }
    }
    return v[N][M];
}

int main(int argc, const char* argv[])
{
    freopen("input.in", "r", stdin);
    freopen("output.out", "w", stdout);
    string str1, str2;
    while(cin >> str1 >> str2)
    {
        cout << LongestIncreasingCommonSubsequence(str1, str2) << endl;
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}

poj_1450_Gridland.cpp

Problem Links:


poj1450,

Problem:


Gridland
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 4402
Accepted: 2510
Description
Background

For years, computer scientists have been trying to find efficient solutions to different computing problems. For some of them efficient algorithms are already available, these are the "easy" problems like sorting, evaluating a polynomial or finding the shortest path in a graph. For the "hard" ones only exponential-time algorithms are known. The traveling-salesman problem belongs to this latter group. Given a set of N towns and roads between these towns, the problem is to compute the shortest path allowing a salesman to visit each of the towns once and only once and return to the starting point.

poj_1363_Rails.cpp

Problem Links:


poj1363, uva00514,

Problem:

Rails
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 14666
Accepted: 5949
Description
There is a famous railway station in PopPush City. Country there is incredibly hilly. The station was built in last century. Unfortunately, funds were extremely limited that time. It was possible to establish only a surface track. Moreover, it turned out that the station could be only a dead-end one (see picture) and due to lack of available space it could have only one track.




poj_1338_UglyNumbers.cpp

Problem Links:


poj1338, UVa00136,

Problem:

Ugly Numbers
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 13375
Accepted: 5897
Description
Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, ...
shows the first 10 ugly numbers. By convention, 1 is included.
Given the integer n,write a program to find and print the n'th ugly number.

poj_1328_Radar_Installation.cpp

Problem Links:


poj1328,

Problem:

Radar Installation
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 24047
Accepted: 5156
Description
Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only cover d distance, so an island in the sea can be covered by a radius installation, if the distance between them is at most d.

We use Cartesian coordinate system, defining the coasting is the x-axis. The sea side is above x-axis, and the land side below. Given the position of each island in the sea, and given the distance of the coverage of the radar installation, your task is to write a program to find the minimal number of radar installations to cover all the islands. Note that the position of an island is represented by its x-y coordinates.


Figure A Sample Input of Radar Installations

poj_1316_Self_Numbers.cpp

Problem Links:


poj1316,

Problem:


Self Numbers
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 14666
Accepted: 8252
Description
In 1949 the Indian mathematician D.R. Kaprekar discovered a class of numbers called self-numbers. For any positive integer n, define d(n) to be n plus the sum of the digits of n. (The d stands for digitadition, a term coined by Kaprekar.) For example, d(75) = 75 + 7 + 5 = 87. Given any positive integer n as a starting point, you can construct the infinite increasing sequence of integers n, d(n), d(d(n)), d(d(d(n))), .... For example, if you start with 33, the next number is 33 + 3 + 3 = 39, the next is 39 + 3 + 9 = 51, the next is 51 + 5 + 1 = 57, and so you generate the sequence

33, 39, 51, 57, 69, 84, 96, 111, 114, 120, 123, 129, 141, ...
The number n is called a generator of d(n). In the sequence above, 33 is a generator of 39, 39 is a generator of 51, 51 is a generator of 57, and so on. Some numbers have more than one generator: for example, 101 has two generators, 91 and 100. A number with no generators is a self-number. There are thirteen self-numbers less than 100: 1, 3, 5, 7, 9, 20, 31, 42, 53, 64, 75, 86, and 97.

poj_3749_破译密码.cpp

Problem Links:


poj1298, poj3749,

Problem:

The Hardest Problem Ever
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 15162
Accepted: 8431
Description
Julius Caesar lived in a time of danger and intrigue. The hardest situation Caesar ever faced was keeping himself alive. In order for him to survive, he decided to create one of the first ciphers. This cipher was so incredibly sound, that no one could figure it out without knowing how it worked.

You are a sub captain of Caesar's army. It is your job to decipher the messages sent by Caesar and provide to your general. The code is simple. For each letter in a plaintext message, you shift it five places to the right to create the secure message (i.e., if the letter is 'A', the cipher text would be 'F'). Since you are creating plain text out of Caesar's messages, you will do the opposite:

poj_1247_Magnificent_Meatballs.cp

Problem Links:


poj1247, nit1174,

Problem:

Magnificent Meatballs
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 4574
Accepted: 3080
Description
Sam and Ella run a catering service. They like to put on a show when serving meatballs to guests seated at round tables. They march out of the kitchen with pots of meatballs and start serving adjacent guests. Ella goes counterclockwise and Sam goes clockwise, until they both plop down their last meatball, at the same time, again at adjacent guests. This impressive routine can only be accomplished if they can divide the table into two sections, each having the same number of meatballs. You are to write a program to assist them.

At these catering events, each table seats 2 <= N <= 30 guests. Each guest orders at least one and at most nine meatballs. Each place at the table is numbered from 1 to N, with the host at position 1 and the host's spouse at position N. Sam always serves the host first then proceeds to serve guests in increasing order. Ella serves the spouse first, then serves guests in decreasing order. The figures illustrate the first two example input cases.

Input
Input consists of one or more test cases. Each test case contains the number of guests N followed by meatballs ordered by each guest, from guest 1 to guest N. The end of the input is a line with a single zero.
Output
For each table, output a single line with the ending positions for Sam and Ella, or the sentence indicating an equal partitioning isn't possible. Use the exact formatting shown below.
Sample Input
5 9 4 2 8 3
5 3 9 4 2 8
6 1 2 1 2 1 2
6 1 2 1 2 1 1
0
Sample Output
Sam stops at position 2 and Ella stops at position 3.
No equal partitioning.
No equal partitioning.
Sam stops at position 3 and Ella stops at position 4.
Source
Mid-Central USA 2002

Solution:


Source Code:

//Sat Jul  3 22:32:26 CDT 2010
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;

int main(int argc, const char* argv[])
{
//  freopen("input.in", "r", stdin);
//  freopen("output.out", "w", stdout);
    int N;
    while (cin >> N)
    {
        if (N == 0)
            break;
        vector<int> v(N);
        for (int i = 0; i < N; i++)
        {
            cin >> v[i];
        }
        int sum1 = 0;
        int sum2 = 0;
        for (int i = 1; i <= N; i++)
        {
            sum1 = 0;
            sum2 = 0;
            for (int p = 0; p < i; p++)
                sum1 += v[p];
            for (int p = i; p < N; p++)
                sum2 += v[p];
            if (sum2 == sum1)
            {
                cout << "Sam stops at position " << i
                        << " and Ella stops at position " << (i + 1) << "."
                        << endl;
                break;
            }
        }
        if (sum1 != sum2)
            cout << "No equal partitioning." << endl;
    }
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

poj_1218_THE_DRUNK_JAILER.cpp

Problem Links:

poj1218,

Problem:

THE DRUNK JAILER
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 15411
Accepted: 9890
Description
A certain prison contains a long hall of n cells, each right next to each other. Each cell has a prisoner in it, and each cell is locked.
One night, the jailer gets bored and decides to play a game. For round 1 of the game, he takes a drink of whiskey,and then runs down the hall unlocking each cell. For round 2, he takes a drink of whiskey, and then runs down the
hall locking every other cell (cells 2, 4, 6, ?). For round 3, he takes a drink of whiskey, and then runs down the hall. He visits every third cell (cells 3, 6, 9, ?). If the cell is locked, he unlocks it; if it is unlocked, he locks it. He
repeats this for n rounds, takes a final drink, and passes out.
Some number of prisoners, possibly zero, realizes that their cells are unlocked and the jailer is incapacitated. They immediately escape.
Given the number of cells, determine how many prisoners escape jail.
Input
The first line of input contains a single positive integer. This is the number of lines that follow. Each of the following lines contains a single integer between 5 and 100, inclusive, which is the number of cells n.
Output
For each line, you must print out the number of prisoners that escape when the prison has n cells.
Sample Input
2
5
100
Sample Output
2
10
Source
Greater New York 2002

Solution:


Source Code:

//Tue Jun  1 14:05:04 EDT 2010
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;

int main(int argc, const char* argv[])
{
//  freopen("input.in", "r", stdin);
//  freopen("output.out", "w", stdout);
    int T;
    cin >> T;
    while (T--)
    {
        int N;
        cin >> N;
        vector<bool> v(N + 1, false);
        for (int i = 2; i <= N; i++)
        {
            for (int j = i; j <= N; j += i)
            {
                v[j] = v[j] ? false : true;
            }
        }
        int sum = 0;
        for (int i = 1; i <= N; i++)
        {
            if (v[i] == true)
                sum++;
        }
        cout << N - sum << endl;
    }
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

poj_1182_食物链.cpp

Problem Links:

poj1182,

Problem:

食物链
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 21064
Accepted: 6073
Description
动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。
现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种。
有人用两种说法对这N个动物所构成的食物链关系进行描述:
第一种说法是"1 X Y",表示X和Y是同类。
第二种说法是"2 X Y",表示X吃Y。
此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
1) 当前的话与前面的某些真的话冲突,就是假话;
2) 当前的话中X或Y比N大,就是假话;
3) 当前的话表示X吃X,就是假话。
你的任务是根据给定的N(1 <= N <= 50,000)和K句话(0 <= K <= 100,000),输出假话的总数。

Input
第一行是两个整数N和K,以一个空格分隔。
以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。
若D=1,则表示X和Y是同类。
若D=2,则表示X吃Y。

Output
只有一个整数,表示假话的数目。

Sample Input
100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5

Sample Output
3

Source
Noi 01

Solution:


Disjoint set structure, find-union algorithms.
PS:
the key part of this problem is connect each other by using rank.
take care of what should the Find function return.
The report from N.

Source Code:

//Fri Jun  4 11:35:32 EDT 2010
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define MMAX 50001
using namespace std;
/* Method One:
 * (v[x].rank-v[y].rank+3)%3==0 表示x与y是同类
 * (v[x].rank-v[y].rank+3)%3==1 表示x吃y
 * (v[x].rank-v[y].rank+3)%3==2 表示y吃x
 *
 * Method Two:
 * rank[x]   表示x与father[x]的关系:
 * rank[x] == 0 表示x与 father[x] 是同类
 * rank[x] == 1 表示x吃 father[x]
 * rank[x] == 0 表示 father[x] 吃x
 * */
class Predator
{
public:
    int parent;
    int rank;
};

vector<Predator> v(MMAX);

void Makeset(int N)
{
    for (int i = 1; i <= N; i++)
    {
        v[i].parent = i;
        v[i].rank = 0;
    }
}

int Find(int x)
{
    if (x == v[x].parent)
        return x;
    int temp = v[x].parent;
    v[x].parent = Find(v[x].parent);
    v[x].rank = (v[x].rank + v[temp].rank) % 3;
    return v[x].parent;
}

void Union(int t1, int t2, int x, int y, int d)
{
    v[t2].parent = t1;
    v[t2].rank = (v[x].rank - v[y].rank + 6 - d) % 3;
}

int main(int argc, const char* argv[])
{
//  freopen("input.in", "r", stdin);
//  freopen("output.out", "w", stdout);
    int N, M;
//  cin >> N >> M;
    scanf("%d%d", &N, &M);
    Makeset(N);
    int score = 0;
    int a, b, c;
    while (M--)
    {
//      cin >> a >> b >> c;
        scanf("%d%d%d", &a, &b, &c);
        if (b > N || c > N || (a == 2 && b == c))
        {
            score++;
            continue;
        }
        int t1 = Find(b);
        int t2 = Find(c);
        if (t1 == t2)
        {
            if (a == 1 && v[b].rank != v[c].rank)
                score++;
            if (a == 2 && (v[b].rank - v[c].rank + 3) % 3 != a - 1)
                score++;
        }
        else
        {
            Union(t1, t2, b, c, a - 1);
        }
    }
    cout << score << endl;
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

poj_1163_The_Triangle.cpp

Problem Links:

poj1163,

Problem:

The Triangle
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 23558
Accepted: 13701



Description

7
3   8
8   1   0
2   7   4   4
4   5   2   6   5

(Figure 1)

poj_1159_Palindrome.cpp

Problem Links:

poj1159,

Problem:


Palindrome


Time Limit: 3000MS

Memory Limit: 65536K

Total Submissions: 31809

Accepted: 10621

Description

A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a program which, given a string, determines the minimal number of characters to be inserted into the string in order to obtain a palindrome.

As an example, by inserting 2 characters, the string "Ab3bd" can be transformed into a palindrome ("dAb3bAd" or "Adb3bdA"). However, inserting fewer than 2 characters does not produce a palindrome.

poj_1157_LITTLE_SHOP_OF_FLOWERS.cpp

Problem Links:

poj1157,

Problem:

LITTLE SHOP OF FLOWERS
Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 10395Accepted: 4809

Description
You want to arrange the window of your flower shop in a most pleasant way. You have F bunches of flowers, each being of a different kind, and at least as many vases ordered in a row. The vases are glued onto the shelf and are numbered consecutively 1 through V, where V is the number of vases, from left to right so that the vase 1 is the leftmost, and the vase V is the rightmost vase. The bunches are moveable and are uniquely identified by integers between 1 and F. These id-numbers have a significance: They determine the required order of appearance of the flower bunches in the row of vases so that the bunch i must be in a vase to the left of the vase containing bunch j whenever i < j. Suppose, for example, you have bunch of azaleas (id-number=1), a bunch of begonias (id-number=2) and a bunch of carnations (id-number=3). Now, all the bunches must be put into the vases keeping their id-numbers in order. The bunch of azaleas must be in a vase to the left of begonias, and the bunch of begonias must be in a vase to the left of carnations. If there are more vases than bunches of flowers then the excess will be left empty. A vase can hold only one bunch of flowers.

Each vase has a distinct characteristic (just like flowers do). Hence, putting a bunch of flowers in a vase results in a certain aesthetic value, expressed by an integer. The aesthetic values are presented in a table as shown below. Leaving a vase empty has an aesthetic value of 0.
 
V A S E S
1
2
3
4
5
Bunches
1 (azaleas)
7 23 -5 -24 16
2 (begonias)
5 21 -4 10 23
3 (carnations)
-21
5 -4 -20 20
According to the table, azaleas, for example, would look great in vase 2, but they would look awful in vase 4.

To achieve the most pleasant effect you have to maximize the sum of aesthetic values for the arrangement while keeping the required ordering of the flowers. If more than one arrangement has the maximal sum value, any one of them will be acceptable. You have to produce exactly one arrangement.

Input
  • The first line contains two numbers: F, V.

  • The following F lines: Each of these lines contains V integers, so that Aij is given as the jth number on the (i+1)st line of the input file.


  • 1 <= F <= 100 where F is the number of the bunches of flowers. The bunches are numbered 1 through F.

  • F <= V <= 100 where V is the number of vases.

  • -50 <= Aij <= 50 where Aij is the aesthetic value obtained by putting the flower bunch i into the vase j.


Output
The first line will contain the sum of aesthetic values for your arrangement.

Sample Input
3 5
7 23 -5 -24 16
5 21 -4 10 23
-21 5 -4 -20 20

Sample Output
53

Source
IOI 1999

Solution:


Source Code:

Version 1:

//Wed 03 Feb 2010 08:10:01 PM CST
#include <iostream>
#include <string>
#include <vector>
#include <cstring>
using namespace std;

int dp[110][110];
int A[110][110];
int main(int argc, char* argv[])
{
    int F, V;
    cin >> F >> V;
    memset(dp, -5001, sizeof(dp));
    for(int i=1; i<=F; i++)
    {
        for(int j=1; j<=V; j++)
        {
            cin >> A[i][j];
        }
    }

    //Initialize: no flowers in each number of vases.
    for(int i=0; i<=V; i++)
        dp[0][i] = 0;
    for(int i=1; i<=F; i++)
    {
        dp[i][i] = dp[i-1][i-1] + A[i][i]; //This one made the greatest change.
        for(int j=i+1; j<=V; j++)
        {
            dp[i][j] = max(dp[i][j-1], dp[i-1][j-1]+A[i][j]);
//          dp[i][j] = max(dp[i-1][j], dp[i-1][j-1]+A[i][j]);
        }
    }
    cout << dp[F][V] << endl;
    return 0;
}

Version 2:

//Thu 04 Feb 2010 01:47:19 AM CST
#include <iostream>
#include <string>
#include <vector>
#include <cstring>
using namespace std;

int dp[110][110];
int A[110][110];
int main(int argc, char* argv[])
{
    int F, V;
    cin >> F >> V;
    memset(dp, -50001, sizeof(dp));
    for(int i=0; i<F; i++)
    {
        for(int j=0; j<V; j++)
        {
            cin >> A[i][j];
        }
    }
    dp[0][0] = A[0][0];
    for(int j=1; j<V; j++)
        dp[0][j] = max(dp[0][j-1], A[0][j]);
    for(int i=1; i<F; i++)
    {
        dp[i][i] = dp[i-1][i-1] + A[i][i];
        for(int j=i+1; j<V; j++)
        {
            dp[i][j] = max(dp[i][j-1], dp[i-1][j-1]+A[i][j]);
        }
    }  
    cout << dp[F-1][V-1] << endl;
    return 0;
}