2013年8月31日 星期六

103 - Stacking Boxes


Background

Some concepts in Mathematics and Computer Science are simple in one or two dimensions but become more complex when extended to arbitrary dimensions. Consider solving differential equations in several dimensions and analyzing the topology of an n-dimensional hypercube. The former is much more complicated than its one dimensional relative while the latter bears a remarkable resemblance to its ``lower-class'' cousin.

The Problem

Consider an n-dimensional ``box'' given by its dimensions. In two dimensions the box (2,3) might represent a box with length 2 units and width 3 units. In three dimensions the box (4,8,9) can represent a box tex2html_wrap_inline40 (length, width, and height). In 6 dimensions it is, perhaps, unclear what the box (4,5,6,7,8,9) represents; but we can analyze properties of the box such as the sum of its dimensions.
In this problem you will analyze a property of a group of n-dimensional boxes. You are to determine the longest nesting string of boxes, that is a sequence of boxes tex2html_wrap_inline44 such that each box tex2html_wrap_inline46 nests in box tex2html_wrap_inline48 ( tex2html_wrap_inline50 .
A box D = ( tex2html_wrap_inline52 ) nests in a box E = ( tex2html_wrap_inline54 ) if there is some rearrangement of the tex2html_wrap_inline56 such that when rearranged each dimension is less than the corresponding dimension in box E. This loosely corresponds to turning box D to see if it will fit in box E. However, since any rearrangement suffices, box D can be contorted, not just turned (see examples below).
For example, the box D = (2,6) nests in the box E = (7,3) since D can be rearranged as (6,2) so that each dimension is less than the corresponding dimension in E. The box D = (9,5,7,3) does NOT nest in the box E = (2,10,6,8) since no rearrangement of D results in a box that satisfies the nesting property, but F = (9,5,7,1) does nest in box E since F can be rearranged as (1,9,5,7) which nests in E.
Formally, we define nesting as follows: box D = ( tex2html_wrap_inline52 ) nests in box E = ( tex2html_wrap_inline54 ) if there is a permutation tex2html_wrap_inline62 of tex2html_wrap_inline64such that ( tex2html_wrap_inline66 ) ``fits'' in ( tex2html_wrap_inline54 ) i.e., if tex2html_wrap_inline70 for all tex2html_wrap_inline72 .

The Input

The input consists of a series of box sequences. Each box sequence begins with a line consisting of the the number of boxes k in the sequence followed by the dimensionality of the boxes, n (on the same line.)
This line is followed by k lines, one line per box with the n measurements of each box on one line separated by one or more spaces. The tex2html_wrap_inline82 line in the sequence ( tex2html_wrap_inline84 ) gives the measurements for the tex2html_wrap_inline82 box.
There may be several box sequences in the input file. Your program should process all of them and determine, for each sequence, which of the kboxes determine the longest nesting string and the length of that nesting string (the number of boxes in the string).
In this problem the maximum dimensionality is 10 and the minimum dimensionality is 1. The maximum number of boxes in a sequence is 30.

The Output

For each box sequence in the input file, output the length of the longest nesting string on one line followed on the next line by a list of the boxes that comprise this string in order. The ``smallest'' or ``innermost'' box of the nesting string should be listed first, the next box (if there is one) should be listed second, etc.
The boxes should be numbered according to the order in which they appeared in the input file (first box is box 1, etc.).
If there is more than one longest nesting string then any one of them can be output.

Sample Input


5 2
3 7
8 10
5 2
9 11
21 18
8 6
5 2 20 1 30 10
23 15 7 9 11 3
40 50 34 24 14 4
9 10 11 12 13 14
31 4 18 8 27 17
44 32 13 19 41 19
1 2 3 4 5 6
80 37 47 18 21 9

Sample Output


5
3 1 2 4 5
4
7 2 5 6


出處: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=39


問題描述

此問題首先會給您盒子的數量,並且告訴您盒子的維度(會超過三維),接著會輸入每一個盒子的邊長,最後要您求出最多可以疊多少個盒子,並且印出疊最多盒子的串列。

解題思路

首先如何判斷盒子A是否可以塞進盒子B裡呢? 根據題目的定義,只要盒子A有任何一種邊長的排列方式可以使得盒子A所有的邊長都比盒子B的邊長來得小,就可以將盒子A塞進盒子B裡。最直接的判斷方法就是把所有盒子的邊長都先排序好,最後只需要從第一個邊長逐一比較到最後一個邊長,若盒子A的每個邊長皆比盒子B來得小,那就表示盒子A可以塞進盒子B裡,否則就不行。至於如何找出可以疊最多盒子的串列呢? 其實此問題可以用dynamic programming的方法來解,也就是使用類floyd-warshall的演算法,把每個盒子視為一個點,把可以疊的盒子數量視為路徑長,最後只需把求最短路徑改成求最長路徑即可。

c++程式碼

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

void findPath(vector< vector<int> >& path, int startVertex, int endVertex) {
    if (path[startVertex][endVertex] != -1) {
        findPath(path, startVertex, path[startVertex][endVertex]);
        cout << " " << path[startVertex][endVertex] + 1;
        findPath(path, path[startVertex][endVertex], endVertex);
    }
}

int main() {
    int boxNum, dimens;

    while (cin >> boxNum >> dimens) {
        vector< vector<int> > boxes(boxNum, vector<int>(dimens, 0));
        vector< vector<int> > pathLength(boxNum, vector<int>(boxNum, 0));
        vector< vector<int> > path(boxNum, vector<int>(boxNum, -1));
        int maxPathLength = -1;
        int startVertex = -1;
        int endVertex = -1;

        for (int i=0; i<boxes.size(); i++) {
            for (int j=0; j<boxes[i].size(); j++)
                cin >> boxes[i][j];
            sort(boxes[i].begin(), boxes[i].end());
        }
        for (int i=0; i<boxes.size(); i++) {
            for (int j=0; j<boxes.size(); j++) {
                bool isNest = true;

                for (int k=0; k<boxes[i].size(); k++) {
                    if (boxes[i][k] >= boxes[j][k]) {
                        isNest = false;
                        break;
                    }
                }
                if (isNest)
                    pathLength[i][j] = 1;
                if (pathLength[i][j] > maxPathLength) {
                    maxPathLength = pathLength[i][j];
                    startVertex = i;
                    endVertex = j;
                }
            }
        }
        for (int k=0; k<boxes.size(); k++) {
            for (int i=0; i<boxes.size(); i++) {
                for (int j=0; j<boxes.size(); j++) {
                    if (pathLength[i][k] != 0 && pathLength[k][j] != 0 && pathLength[i][k] + pathLength[k][j] > pathLength[i][j]) {
                        pathLength[i][j] = pathLength[i][k] + pathLength[k][j];
                        path[i][j] = k;
                        if (pathLength[i][j] > maxPathLength) {
                            maxPathLength = pathLength[i][j];
                            startVertex = i;
                            endVertex = j;
                        }
                    }
                }
            }
        }
        cout << maxPathLength + 1 << endl;
        cout << startVertex + 1;
        if (maxPathLength) {
            findPath(path, startVertex, endVertex);
            cout << " " << endVertex + 1 << endl;
        }
        else
            cout << endl;
    }

    return 0;
}

2013年8月23日 星期五

10940 - Throwing cards away II

Given is an ordered deck of n cards numbered 1 to n with card 1 at the top and card n at the bottom. The following operation is performed as long as there are at least two cards in the deck:
Throw away the top card and move the card that is now on the top of the deck to the bottom of the deck.
Your task is to find the last, remaining card.
Each line of input (except the last) contains a positive number n ≤ 500000. The last line contains 0 and this line should not be processed. For each number from input produce one line of output giving the last remaining card. Input will not contain more than 500000 lines.

Sample input

7
19
10
6
0

Output for sample input

6
6
4
4

出處: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1881



此題的操作具有遞迴關係。首先2張牌的情況,經過題目所說的操作答案就是第2張牌,至於3張牌的情況,經過題目所說的操作之後會變成2張牌的情況,4張牌的情況經過操作之後會變成3張牌的情況 ... n張牌的情況經過操作會變成n - 1張牌的情況。所以每個情況的解都可以由前一個情況來推算,利用dynamic programming的觀念,先把2到500000張牌的每個情況都推算出來並且記起來,接下來就看題目要的是哪個情況就把哪個情況的解叫出來就好了。至於如何從n - 1張牌情況的解推出n張牌情況的解呢?若n - 1張牌情況的解是最後一張,則n張牌情況的解就是第2張,若n - 1張情況的解不是最後一張,那這個解的位置加上2就是n張牌情況的解。此題還有一點要注意的是若輸入是1則輸出就是1,因為無法進行任何操作。

c++ code:

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

int main() {
    map<int, int> table;

    table[1] = 1;
    table[2] = 2;
    for (int i=3; i<=500000; i++) {
        if (table[i - 1] == i - 1)
            table[i] = 2;
        else
            table[i] = table[i - 1] + 2;
    }
    while (true) {
        int n;

        cin >> n;
        if (!n)
            break;
        cout << table[n] << endl;
    }

    return 0;
}

2013年8月18日 星期日

913 - Joana and the Odd Numbers

Joana loves playing with odd numbers. In the other day, she started writing, in each line, an odd number of odd numbers. It looked as follows:
 1
 3  5  7
 9 11 13 15 17
19 21 23 25 27 29 31
...
On a certain line Joana wrote 55 odd numbers. Can you discover the sum of the last three numbers written in that line? Can you do this more generally for a given quantity of odd numbers?

Problem

Given the number N of odd numbers in a certain line, your task is to determine the sum of the last three numbers of that line.

Input

The input is a sequence of lines, one odd number N (1<N<1000000000) per line

Output

For each input line write the sum of the last three odd numbers written by Joana in that line with N numbers. This sum is guaranteed to be less than 263.

Sample Input

3
5
7

Sample Output


15
45
87

出處: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=854



這一題題目是給您其中某一列奇數的數目,接著要您求出這一列最後三個奇數的總和。如果這一題用暴力解法應該會超過time limit,因為測試資料的範圍是1<N<1000000000,所以此題不能用暴力解。可以先思考一下題目要您求出的答案是"某一奇數列的最後三個數字的總和",所以其實只要知道這三個數字的其中一個數字就好了,因為其他兩個數字可以推淂。既然如此我們可以選擇先求最後一個數字,因為最後一個數字比較好從規律推到,可以觀察一下題目的規律來推出最後一個數字:

若輸入為3, 最後一個數字為:

1 + 3 * 2 = 7

則三數總和為:

3 + 5 + 7 = 15

若輸入為5, 最後一個數字為:

1 + 3 * 2 + 5 * 2 = 17

則三數總和為:

17 + 15 + 13 = 45
.
.
.
若輸入為n, 最後一個數字為:

1 + 3 * 2 + 5 * 2  + ... + n * 2 = a

則三數總和為:

a + a - 2 + a - 4 = 3 * a - 6

至於1 + 3 * 2 + 5 * 2  + ... + n * 2 = a這個算式可以簡化成以下式子:

1 + 2 * (3 + 5 + ... + n) = a

而括弧裡面的式子就是等差級數,所以利用等差級數公式代掉後變成以下算式:

1 + 2 * (3 + n) * (n - 1) / 2 / 2

整理一下可以變成此式:

(n ^ 2 + 2 * n - 1) / 2 = a

最後再把a代入3 * a - 6就變成以下式子:

3 * (n ^ 2 + 2 * n - 1) / 2 - 6

接著可以簡化成

3 * (n ^ 2 + 2 * n - 5) / 2

這就是最終公式,把input代入即可求解。還有一個要注意的是若資料型態用int會容納不下最終解,所以必須要用更大的資料型態來儲存。

以下是c++ code:

#include <iostream>
using namespace std;

int main() {
    long long n;

    while (cin >> n)
        cout << 3 * (n * n + 2 * n - 5) / 2  << endl;

    return 0;
}

591 - Box of Bricks

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?


Input 

The input consists of several data sets. Each set begins with a line containing the number n of stacks Bob has built. The next line contains nnumbers, the heights hi of the n stacks. You may assume $1 Ÿ\le n \leŸ 50$ and $1 \leŸ h_i Ÿ\le 100$.
The total number of bricks will be divisible by the number of stacks. Thus, it is always possible to rearrange the bricks such that all stacks have the same height.
The input is terminated by a set starting with n = 0. This set should not be processed.

Output 

For each set, first print the number of the set, as shown in the sample output. Then print the line ``The minimum number of moves is k.'', wherek is the minimum number of bricks that have to be moved in order to make all the stacks the same height.
Output a blank line after each set.

Sample Input 

6
5 2 4 1 7 5
0

Sample Output 

Set #1
The minimum number of moves is 5.

出處: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=7&page=show_problem&problem=532



題目要求您要用最少的移動次數移動積木,來把每一堆積木都變得一樣高,題目假設總積木數除以積木堆數都有辦法整除,也就是說積木經過移動後都有辦法變得一樣高。既然要用最少的次數移動,那每一次移動就要把最高的積木堆拿一個積木下來填補到最低的積木堆,一直到每個積木堆都一樣高為止。

c++ code:

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

int main() {
    int setCount = 0;

    while (true) {
        int n;
        vector<int> heights;
        int moveCount = 0;

        cin >> n;
        if (n == 0)
            break;
        setCount++;
        for (int i=0; i<n; i++) {
            int h;

            cin >> h;
            heights.push_back(h);
        }
        while (true) {
            int max = heights[0];
            int min = heights[0];
            int maxIndex = 0;
            int minIndex = 0;

            for (int i=1; i<heights.size(); i++) {
                if (heights[i] > max) {
                    max = heights[i];
                    maxIndex = i;
                }
                else if (heights[i] < min) {
                    min = heights[i];
                    minIndex = i;
                }
            }
            if (max == min)
                break;
            moveCount++;
            heights[maxIndex]--;
            heights[minIndex]++;
        }
        cout << "Set #" << setCount << endl;
        cout << "The minimum number of moves is " << moveCount << ".\n\n";
    }

    return 0;
}

2013年8月17日 星期六

579 - ClockHands

The medieval interest in mechanical contrivances is well illustrated by the development of the mechanical clock, the oldest of which is driven by weights and controlled by a verge, an oscillating arm engaging with a gear wheel. It dates back to 1386.
Clocks driven by springs had appeared by the mid-15th century, making it possible to con- struct more compact mechanisms and preparing the way for the portable clock.
English spring-driven pendulum clocks were first commonly kept on a small wall bracket and later on a shelf. Many bracket clocks contained a drawer to hold the winding key. The earliest bracket clocks, made for a period after 1660, were of architectural design, with pillars at the sides and a pediment on top.
In 17th- and 18th-century France, the table clock became an object of monumental design, the best examples of which are minor works of sculpture.
The longcase clocks (also called grandfather clocks) are tall pendulum clock enclosed in a wooden case that stands upon the floor and is typically from 6 to 7.5 feet (1.8 to 2.3 m) in height. Later, the name ``grandfather clock'' became popular after the popular song "My Grandfather's Clock," written in 1876 by Henry Clay Work.


One of the first atomic clocks was an ammonia-controlled clock. It was built in 1949 at the National Bureau of Standards, Washington, D.C.; in this clock the frequency did not vary by more than one part in 108
Nuclear clocks are built using two clocks. The aggregate of atoms that emit the gamma radiation of precise frequency may be called the emitter clock; the group of atoms that absorb this radiation is the absorber clock. One pair of these nuclear clocks can detect energy changes of one part in 1014 , being about 1,000 times more sensitive than the best atomic clock.
The cesium clock is the most accurate type of clock yet developed. This device makes use of transitions between the spin states of the cesium nucleus and produces a frequency which is so regular that it has been adopted for establishing the time standard.


The history of clocks is fascinating, but unrelated to this problem. In this problem, you are asked to find the angle between the minute hand and the hour hand on a regular analog clock. Assume that the second hand, if there were one, would be pointing straight up at the 12. Give all angles as the smallest positive angles. For example 9:00 is 90 degrees; not -90 or 270 degrees.

Input 

The input is a list of times in the form H:M, each on their own line, with $1 \le H \le 12$ and $00 \le M \le 59$. The input is terminated with the time 0:00. Note that H may be represented with 1 or 2 digits (for 1-9 or 10-12, respectively); M is always represented with 2 digits (The input times are what you typically see on a digital clock).

Output 

The output displays the smallest positive angle in degrees between the hands for each time. The answer should between 0 degrees and 180degrees for all input times. Display each angle on a line by itself in the same order as the input. The output should be rounded to the nearest 1/1000, i.e., three places after the decimal point should be printed.

Sample Input 

12:00
9:00
8:10
0:00

Sample Output 

0.000
90.000
175.000

出處: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=520



這題是計算時針和分針之間夾角的角度(0<=角度<=180),我計算的方式是先算出時針與12點的夾角再扣掉分針與12點的夾角再加上時針隨著分針移動的角度取絕對值,最後再判斷這個角度是否大於180,若大於180則用360去扣掉此角度算出比較小的夾角,若沒有則本身就是比較小的夾角。

c++ code:

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;

int main() {
    string time;

    while (true) {
        int hour = 0;
        int min = 0;
        int i;
        double angle;

        cin >> time;
        if (time == "0:00")
            break;
        for (i=0; time[i]!=':'; i++)
            hour = hour * 10 + time[i] - '0';
        for (i=i+1; i<time.length(); i++)
            min = min * 10 + time[i] - '0';
        angle = abs(hour * 5 * 6 - min * 6 + min / 2.);
        if (angle > 180)
            cout << setprecision(3) << fixed << (360 - angle) << endl;
        else
            cout << setprecision(3) << fixed << angle << endl;
    }

    return 0;
}

494 - Kindergarten Counting Game

Everybody sit down in a circle. Ok. Listen to me carefully.
``Woooooo, you scwewy wabbit!''
Now, could someone tell me how many words I just said?

Input and Output

Input to your program will consist of a series of lines, each line containing multiple words (at least one). A ``word'' is defined as a consecutive sequence of letters (upper and/or lower case).

Your program should output a word count for each line of input. Each word count should be printed on a separate line.

Sample Input


Meep Meep!
I tot I taw a putty tat.
I did! I did! I did taw a putty tat.
Shsssssssssh ... I am hunting wabbits. Heh Heh Heh Heh ...

Sample Output


2
7
10
9

出處: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=435



這題是要求您去數有幾個英文單字,這邊一個單字的定義是連續的大寫或小寫英文字母就算一個單字,所以只要搭配布林變數就可以解決此題。當遇到第一個英文字母的時候將布林設定為true並且單字數加一,當遇到不是英文字母的時候就將布林改為false,依此類推就可以數出有幾個英文單字。

c++ code:

#include <iostream>
using namespace std;

int main() {
    string line;

    while (getline(cin, line)) {
        bool flag = false;
        int count = 0;

        for (int i=0; i<line.length(); i++) {
            if ((line[i] >= 'A' && line[i] <= 'Z') || (line[i] >= 'a' && line[i] <= 'z')) {
                if (!flag) {
                    count++;
                    flag = true;
                }
            }
            else
                flag = false;
        }
        cout << count << endl;
    }

    return 0;
}

2013年8月16日 星期五

488 - Triangle Wave

In this problem you are to generate a triangular wave form according to a specified pair of Amplitude and Frequency.

Input and Output

The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.
Each input set will contain two integers, each on a separate line. The first integer is the Amplitude; the second integer is the Frequency.
For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.
For the output of your program, you will be printing wave forms each separated by a blank line. The total number of wave forms equals the Frequency, and the horizontal ``height'' of each wave equals the Amplitude. The Amplitude will never be greater than nine.
The waveform itself should be filled with integers on each line which indicate the ``height'' of that line.
NOTE: There is a blank line after each separate waveform, excluding the last one.

Sample Input


1

3
2

Sample Output


1
22
333
22
1

1
22
333
22
1
 

出處: UVa Online Judge - Triangle Wave


問題敘述

題目會先輸入共有幾組測試資料,接著輸入每組測試資料的內容。各組測試資料有兩個整數,第一個整數是振幅,第二個整數是頻率,此題要求您依照振幅和頻率印出波形。

解題思路

沒有什麼思路,只要印出和振幅一樣高的波並且重複印出題目給的頻率次即可。

c++ 程式碼

#include <iostream>
using namespace std;

int main() {
    int n;
    bool isFirst = true;

    cin >> n;
    for (int i=0; i<n; i++) {
        int amp, fre;

        cin.get();
        cin >> amp >> fre;
        for (int j=0; j<fre; j++) {
            bool reverse = false;

            if (isFirst)
                isFirst = false;
            else
                cout << endl;
            for (int k=1; k>=1; (reverse)? k--:k++) {
                for (int m=1; m<=k; m++)
                    cout << k;
                cout << endl;
                if (k == amp)
                    reverse = true;
            }
        }
    }

    return 0;
}

2013年8月12日 星期一

477 - Points in Figures: Rectangles and Circles

Given a list of figures (rectangles and circles) and a list of points in the x-y plane, determine for each point which figures (if any) contain the point.

Input

There will be ntex2html_wrap_inline232 ) figures descriptions, one per line. The first character will designate the type of figure (``r'', ``c'' for rectangle or circle, respectively). This character will be followed by values which describe that figure.
  • For a rectangle, there will be four real values designating the x-y coordinates of the upper left and lower right corners.
  • For a circle, there will be three real values, designating the x-y coordinates of the center and the radius.
The end of the list will be signalled by a line containing an asterisk in column one.

The remaining lines will contain the x-y coordinates, one per line, of the points to be tested. The end of this list will be indicated by a point with coordinates 9999.9 9999.9; these values should not be included in the output.
Points coinciding with a figure border are not considered inside.

Output

For each point to be tested, write a message of the form:
Point i is contained in figure j
for each figure that contains that point. If the point is not contained in any figure, write a message of the form:
Point i is not contained in any figure
Points and figures should be numbered in the order in which they appear in the input.

Sample Input


r 8.5 17.0 25.5 -8.5
c 20.2 7.3 5.8
r 0.0 10.3 5.5 0.0
c -5.0 -5.0 3.7
r 2.5 12.5 12.5 2.5
c 5.0 15.0 7.2
*
2.0 2.0
4.7 5.3
6.9 11.2
20.0 20.0
17.6 3.2
-5.2 -7.8
9999.9 9999.9

Sample Output


Point 1 is contained in figure 3
Point 2 is contained in figure 3
Point 2 is contained in figure 5
Point 3 is contained in figure 5
Point 3 is contained in figure 6
Point 4 is not contained in any figure
Point 5 is contained in figure 1
Point 5 is contained in figure 2
Point 6 is contained in figure 4

Diagrama of sample input figures and data points

出處: UVa Online Judge - Points in Figures: Rectangles and Circles


問題敘述

這題是 476 - Points in Figures: Rectangles (Chinese version) 這一題的擴充,一樣是判斷點有沒有在圖形內,只不過多增加了圓形。

解題思路

如何判斷點有沒有在矩形內在上一題就已經說明過,所以不再贅述。至於如何判斷點有沒有在圓形內就是算出點和圓心之間的距離並且判斷此距離有沒有小於半徑即可。為了操作方便,程式裡用了點繼承的小技巧,來達到一樣是Figure但是長方形和圓形各有不同判斷點是否在圖形內的方法的效果。

c++ 程式碼

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

class Point {
    public:
        double x, y;
        Point(double, double);
};

Point::Point(double x, double y):x(x), y(y) {
}

class Figure {
    public:
        virtual bool contain(Point*) = 0;
};

class Rectangle: public Figure {
    public:
        double x1, y1, x2, y2;
        Rectangle(double, double, double, double);
        bool contain(Point*);
};

Rectangle::Rectangle(double x1, double y1, double x2, double y2):x1(x1), y1(y1), x2(x2), y2(y2) {
}

bool Rectangle::contain(Point* point) {
    if (this->x1 < point->x && point->x < this->x2 && this->y1 > point->y && point->y > this->y2)
        return true;
    else
        return false;
}

class Circle: public Figure {
    public:
        double x, y, radius;
        Circle(double, double, double);
        bool contain(Point*);
};

Circle::Circle(double x, double y, double radius):x(x), y(y), radius(radius) {
}

bool Circle::contain(Point* point) {
    double dis = sqrt(pow(this->x - point->x, 2) + pow(this->y - point->y, 2));

    if (dis < radius)
        return true;
    else
        return false;
}

int main() {
    vector<Figure*> figVec;
    vector<Point*> pointVec;

    while (true) {
        char sym;

        cin >> sym;
        if (sym == '*')
            break;
        else if (sym == 'r') {
            double x1, y1, x2, y2;
            Rectangle* rec;

            cin >> x1 >> y1 >> x2 >> y2;
            rec = new Rectangle(x1, y1, x2, y2);
            figVec.push_back(rec);
        }
        else {
            double x, y, radius;
            Circle* circle;

            cin >> x >> y >> radius;
            circle = new Circle(x, y, radius);
            figVec.push_back(circle);
        }
    }
    while (true) {
        double x, y;
        Point* point;

        cin >> x >> y;
        if (x == 9999.9 && y == 9999.9)
            break;
        point = new Point(x, y);
        pointVec.push_back(point);
    }
    for (int i=0; i<pointVec.size(); i++) {
        bool isContained = false;

        for (int j=0; j<figVec.size(); j++) {
            if (figVec[j]->contain(pointVec[i])) {
                cout << "Point " << i + 1 << " is contained in figure " << j + 1 << endl;
                isContained = true;
            }
        }
        if (!isContained)
            cout << "Point " << i + 1 << " is not contained in any figure" << endl;
    }
    for (int i=0; i<figVec.size(); i++)
        delete figVec[i];
    for (int i=0; i<pointVec.size(); i++)
        delete pointVec[i];

    return 0;
}

476 - Points in Figures: Rectangles

Given a list of rectangles and a list of points in the x-y plane, determine for each point which figures (if any) contain the point.

Input

There will be ntex2html_wrap_inline220 ) rectangles descriptions, one per line. The first character will designate the type of figure (``r'' for rectangle). This character will be followed by four real values designating the x-y coordinates of the upper left and lower right corners.
The end of the list will be signalled by a line containing an asterisk in column one.

The remaining lines will contain the x-y coordinates, one per line, of the points to be tested. The end of this list will be indicated by a point with coordinates 9999.9 9999.9; these values should not be included in the output.
Points coinciding with a figure border are not considered inside.

Output

For each point to be tested, write a message of the form:
Point i is contained in figure j
for each figure that contains that point. If the point is not contained in any figure, write a message of the form:
Point i is not contained in any figure
Points and figures should be numbered in the order in which they appear in the input.

Sample Input


r 8.5 17.0 25.5 -8.5
r 0.0 10.3 5.5 0.0
r 2.5 12.5 12.5 2.5
*
2.0 2.0
4.7 5.3
6.9 11.2
20.0 20.0
17.6 3.2
-5.2 -7.8
9999.9 9999.9

Sample Output


Point 1 is contained in figure 2
Point 2 is contained in figure 2
Point 2 is contained in figure 3
Point 3 is contained in figure 3
Point 4 is not contained in any figure
Point 5 is contained in figure 1
Point 6 is not contained in any figure

Diagrama of sample input figures and data points

出處: UVa Online Judge - Points in Figures: Rectangles


問題敘述

此題會先輸入很多行長方形座標資料,每行的開頭為 r 代表長方形,接著會輸入四個浮點數,前兩個浮點數代表此長方形左上角的座標,後兩個浮點數代表此長方形右下角的座標,長方形資料一直輸入到出現 * 就結束。接著會輸入很多行成對的浮點數,每對各代表一個點座標,您的任務是要求出這些點各被包含在哪些長方形裡面。

解題思路

因為矩形的輸入資料只給出左上角的座標(設: x1, y1)以及右下角的座標(設: x2, y2),所以可以知道 x1 <= x2 和 y1 >= y2。若點(設 x, y)要落在矩形裡勢必要符合此條件: x1 < x < x2 and y1 > y > y2(沒有等於,因為落在邊上不算被包含在裡面),依照此規則就可以判斷點是否落在矩形內。

c++ 程式碼

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

class Figure {
    public:
        double x1, y1, x2, y2;
        Figure(double, double, double, double);
};

Figure::Figure(double x1, double y1, double x2, double y2):x1(x1), y1(y1), x2(x2), y2(y2) {
}

class Point {
    public:
        double x, y;
        Point(double, double);
};

Point::Point(double x, double y):x(x), y(y) {
}

int main() {
    vector<Figure*> figVec;
    vector<Point*> pointVec;

    while (true) {
        char sym;
        double x1, y1, x2, y2;
        Figure* fig;

        cin >> sym;
        if (sym == '*')
            break;
        cin >> x1 >> y1 >> x2 >> y2;
        fig = new Figure(x1, y1, x2, y2);
        figVec.push_back(fig);
    }
    while (true) {
        double x, y;
        Point* point;

        cin >> x >> y;
        if (x == 9999.9 && y == 9999.9)
            break;
        point = new Point(x, y);
        pointVec.push_back(point);
    }
    for (int i=0; i<pointVec.size(); i++) {
        bool isContained = false;

        for (int j=0; j<figVec.size(); j++) {
            if (figVec[j]->x1 < pointVec[i]->x && pointVec[i]->x < figVec[j]->x2 &&
                    figVec[j]->y1 > pointVec[i]->y && pointVec[i]->y > figVec[j]->y2) {
                cout << "Point " << i + 1 << " is contained in figure " << j + 1 << endl;
                isContained = true;
            }
        }
        if (!isContained)
            cout << "Point " << i + 1 << " is not contained in any figure" << endl;
    }
    for (int i=0; i<figVec.size(); i++)
        delete figVec[i];
    for (int i=0; i<pointVec.size(); i++)
        delete pointVec[i];

    return 0;
}

2013年8月10日 星期六

458 - The Decoder

Write a complete program that will correctly decode a set of characters into a valid message. Your program should read a given file of a simple coded set of characters and print the exact message that the characters contain. The code key for this simple coding is a one for one character substitution based upon a single arithmetic manipulation of the printable portion of the ASCII character set.

Input and Output

For example: with the input file that contains:

1JKJ'pz'{ol'{yhklthyr'vm'{ol'Jvu{yvs'Kh{h'Jvywvyh{pvu5
1PIT'pz'h'{yhklthyr'vm'{ol'Pu{lyuh{pvuhs'I|zpulzz'Thjopul'Jvywvyh{pvu5
1KLJ'pz'{ol'{yhklthyr'vm'{ol'Kpnp{hs'Lx|pwtlu{'Jvywvyh{pvu5
your program should print the message:
*CDC is the trademark of the Control Data Corporation.
*IBM is a trademark of the International Business Machine Corporation.
*DEC is the trademark of the Digital Equipment Corporation.
Your program should accept all sets of characters that use the same encoding scheme and should print the actual message of each set of characters.

Sample Input


1JKJ'pz'{ol'{yhklthyr'vm'{ol'Jvu{yvs'Kh{h'Jvywvyh{pvu5
1PIT'pz'h'{yhklthyr'vm'{ol'Pu{lyuh{pvuhs'I|zpulzz'Thjopul'Jvywvyh{pvu5
1KLJ'pz'{ol'{yhklthyr'vm'{ol'Kpnp{hs'Lx|pwtlu{'Jvywvyh{pvu5

Sample Output


*CDC is the trademark of the Control Data Corporation.
*IBM is a trademark of the International Business Machine Corporation.
*DEC is the trademark of the Digital Equipment Corporation.
 

出處: UVa Online Judge - The Decoder




問題敘述

此題會輸入一個亂七八糟的文本,要您把它解碼成看得懂的文本輸出。

解題思路

此題的輸入文本對應輸出文本有非常明顯的規律,輸入每個字元的 ascii code 減去7就是輸出的字元。

c++ 程式碼

#include <iostream>
using namespace std;

int main() {
    string input;

    while (getline(cin, input)) {
        for (int i=0; i<input.length(); i++)
            cout << (char)(input[i] - 7);
        cout << endl;
    }

    return 0;
}

272 - TEX Quotes

TeX is a typesetting language developed by Donald Knuth. It takes source text together with a few typesetting instructions and produces, one hopes, a beautiful document. Beautiful documents use `` and " to delimit quotations, rather than the mundane " which is what is provided by most keyboards. Keyboards typically do not have an oriented double-quote, but they do have a left-single-quote ` and a right-single-quote '. Check your keyboard now to locate the left-single-quote key ` (sometimes called the ``backquote key") and the right-single-quote key ' (sometimes called the ``apostrophe" or just ``quote"). Be careful not to confuse the left-single-quote ` with the ``backslash" key \. TeX lets the user type two left-single-quotes `` to create a left-double-quote `` and two right-single-quotes '' to create a right-double-quote ''. Most typists, however, are accustomed to delimiting their quotations with the un-oriented double-quote ".

If the source contained
"To be or not to be," quoth the bard, "that is the question."
then the typeset document produced by TeX would not contain the desired form:


``To be or not to be," quoth the bard, ``that is the question."

In order to produce the desired form, the source file must contain the sequence:
``To be or not to be,'' quoth the bard, ``that is the question.''

You are to write a program which converts text containing double-quote (") characters into text that is identical except that double-quotes have been replaced by the two-character sequences required by TeX for delimiting quotations with oriented double-quotes. The double-quote (") characters should be replaced appropriately by either `` if the " opens a quotation and by '' if the " closes a quotation. Notice that the question of nested quotations does not arise: The first " must be replaced by ``, the next by '', the next by ``, the next by '', the next by ``, the next by'', and so on.

Input and Output

Input will consist of several lines of text containing an even number of double-quote (") characters. Input is ended with an end-of-file character. The text must be output exactly as it was input except that:

  • the first " in each pair is replaced by two ` characters: `` and
  • the second " in each pair is replaced by two ' characters: ''.

Sample Input


"To be or not to be," quoth the Bard, "that
is the question".
The programming contestant replied: "I must disagree.
To `C' or not to `C', that is The Question!"

Sample Output


``To be or not to be,'' quoth the Bard, ``that
is the question''.
The programming contestant replied: ``I must disagree.
To `C' or not to `C', that is The Question!''
 
出處: UVa Online Judge - TEX Quotes


問題敘述

此題會輸入一個文本,文本中包含空白和換行,要求您把成對的 " 改成 `` 開頭和 '' (兩個單引號) 結尾。

解題思路

沒有什麼思路,就是把第奇數次出現的 " 改成 ``,第偶數次出現的 " 改成 '' (兩個單引號),其他的字元就直接輸出即可。

c++ 程式碼

#include <iostream>
using namespace std;

int main() {
    string temp;
    int num = 0;

    while (getline(cin, temp)) {
        for (int i=0; i<temp.length(); i++) {
            if (temp[i] == '"') {
                num++;
                if (num % 2)
                    cout << "``";
                else
                    cout << "''";
            }
            else
                cout << temp[i];
        }
        cout << endl;
    }

    return 0;
}