顯示具有 UVa online judge 標籤的文章。 顯示所有文章
顯示具有 UVa online judge 標籤的文章。 顯示所有文章

2016年8月8日 星期一

107 - The Cat in the Hat

The Cat in the Hat 

Background

(An homage to Theodore Seuss Geisel)
The Cat in the Hat is a nasty creature,
But the striped hat he is wearing has a rather nifty feature.
With one flick of his wrist he pops his top off.
Do you know what's inside that Cat's hat?
A bunch of small cats, each with its own striped hat.
Each little cat does the same as line three,
All except the littlest ones, who just say ``Why me?''
Because the littlest cats have to clean all the grime,
And they're tired of doing it time after time!

The Problem

A clever cat walks into a messy room which he needs to clean. Instead of doing the work alone, it decides to have its helper cats do the work. It keeps its (smaller) helper cats inside its hat. Each helper cat also has helper cats in its own hat, and so on. Eventually, the cats reach a smallest size. These smallest cats have no additional cats in their hats. These unfortunate smallest cats have to do the cleaning.
The number of cats inside each (non-smallest) cat's hat is a constant, N. The height of these cats-in-a-hat is tex2html_wrap_inline35 times the height of the cat whose hat they are in.
The smallest cats are of height one;
these are the cats that get the work done.
All heights are positive integers. Given the height of the initial cat and the number of worker cats (of height one), find the number of cats that are not doing any work (cats of height greater than one) and also determine the sum of all the cats' heights (the height of a stack of all cats standing one on top of another).

The Input

The input consists of a sequence of cat-in-hat specifications. Each specification is a single line consisting of two positive integers, separated by white space. The first integer is the height of the initial cat, and the second integer is the number of worker cats.
A pair of 0's on a line indicates the end of input.

The Output

For each input line (cat-in-hat specification), print the number of cats that are not working, followed by a space, followed by the height of the stack of cats. There should be one output line for each input line other than the ``0 0'' that terminates input.

Sample Input

216 125
5764801 1679616
0 0

Sample Output

31 671
335923 30275911
 
出處: UVa Online Judge - The Cat in the Hat


問題敘述

現在有貓咪進去一個房間,房間非常髒亂所以需要打掃,但是這個貓咪不想自己掃地,所以牠戴了頂帽子把別的小貓咪裝進去,要別的小貓咪打掃(好奸詐)。不過在帽子裡面的小貓咪可以再戴帽子裝更小的貓咪,一直裝到小到沒有戴帽子的貓咪就要打掃了(真可憐)。裝貓咪的過程有個數學規律在裡面,就是假設此貓咪的身高為 h,帽子可以裝的貓咪數量為 n,則帽子裡面的貓咪身高為 h / (n + 1),最小的貓咪身高為1(即不能再戴帽子且要打掃的貓咪)。題目每組資料會輸入兩個整數,第一個整數為第一個貓咪的身高,第二個整數為最後要打掃的貓咪數量,要求您輸出兩個整數,第一個整數為沒有打掃的貓咪數量,第二個整數為所有貓咪的總身高為多少。

解題思路

此題很明顯是數學題,首先我們把算式列出來:

設 n 為帽子可以裝貓咪的數量、k 為某個非負整數、c 為最後要打掃的貓咪數量、h 為初始貓咪的身高,可以列出以下兩個式子

n ^ k = c
h * (1 / (n + 1)) ^ k = 1

先將兩個算式都取 log

k * log(n) = log(c)
k * log(n + 1) = log(h)

將上面的算式除以下面的算式可以得到以下

log(n) / log(n + 1) = log(c) / log(h)

接著我們只要找出 n 讓等式成立就可以知道帽子裡可以裝多少貓咪了。知道 n 之後剩下的工作就相當簡單了,可以依據以下算式求出沒在打掃的貓咪:

n ^ 0 + n ^ 1 + ... + n ^ (k - 2) + n ^ (k - 1)

至於總身高可以由以下算式求出:

h * (n ^ 0) + (h / (n + 1)) * (n ^ 1) + ... + (h / (n + 1) ^ (k - 1)) * n ^ (k - 1) + (h / (n + 1) ^ k) * n ^ k

c++ 程式碼

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

int main() {
    while (true) {
        int initHeight, workCat, n, k, height;
        double rightC;
        int notWorkCat = 0;
        int totalHeight = 0;

        cin >> initHeight >> workCat;
        if (!initHeight && !workCat)
            break;
        if (workCat == 1)
            n = 1;
        else {
            rightC = log(initHeight) / log(workCat);
            for (n=2;; n++) {
                double leftC = log(n + 1) / log(n);

                if (leftC - rightC <= 0.0000000001)
                    break;
            }
        }
        k = round(log(initHeight) / log(n + 1));
        height = initHeight;
        for (int i=0; i<k; i++) {
            int cats = pow(n, i);

            notWorkCat += cats;
            totalHeight += height * cats;
            height /= n + 1;
        }
        cout << notWorkCat << " " << totalHeight + workCat << endl;
    }

    return 0;
}

2014年4月19日 星期六

118 - Mutant Flatworld Explorers

Background

Robotics, robot motion planning, and machine learning are areas that cross the boundaries of many of the subdisciplines that comprise Computer Science: artificial intelligence, algorithms and complexity, electrical and mechanical engineering to name a few. In addition, robots as ``turtles'' (inspired by work by Papert, Abelson, and diSessa) and as ``beeper-pickers'' (inspired by work by Pattis) have been studied and used by students as an introduction to programming for many years.
This problem involves determining the position of a robot exploring a pre-Columbian flat world.

The Problem

Given the dimensions of a rectangular grid and a sequence of robot positions and instructions, you are to write a program that determines for each sequence of robot positions and instructions the final position of the robot.
A robot position consists of a grid coordinate (a pair of integers: x-coordinate followed by y-coordinate) and an orientation (N,S,E,W for north, south, east, and west). A robot instruction is a string of the letters 'L', 'R', and 'F' which represent, respectively, the instructions:
  • Left: the robot turns left 90 degrees and remains on the current grid point.
  • Right: the robot turns right 90 degrees and remains on the current grid point.
  • Forward: the robot moves forward one grid point in the direction of the current orientation and mantains the same orientation.
The direction North corresponds to the direction from grid point (x,y) to grid point (x,y+1).
Since the grid is rectangular and bounded, a robot that moves ``off'' an edge of the grid is lost forever. However, lost robots leave a robot ``scent'' that prohibits future robots from dropping off the world at the same grid point. The scent is left at the last grid position the robot occupied before disappearing over the edge. An instruction to move ``off'' the world from a grid point from which a robot has been previously lost is simply ignored by the current robot.

The Input

The first line of input is the upper-right coordinates of the rectangular world, the lower-left coordinates are assumed to be 0,0.
The remaining input consists of a sequence of robot positions and instructions (two lines per robot). A position consists of two integers specifying the initial coordinates of the robot and an orientation (N,S,E,W), all separated by white space on one line. A robot instruction is a string of the letters 'L', 'R', and 'F' on one line.
Each robot is processed sequentially, i.e., finishes executing the robot instructions before the next robot begins execution.
Input is terminated by end-of-file.
You may assume that all initial robot positions are within the bounds of the specified grid. The maximum value for any coordinate is 50. All instruction strings will be less than 100 characters in length.

The Output

For each robot position/instruction in the input, the output should indicate the final grid position and orientation of the robot. If a robot falls off the edge of the grid the word ``LOST'' should be printed after the position and orientation.

Sample Input

5 3
1 1 E
RFRFRFRF
3 2 N
FRRFLLFFRRFLL
0 3 W
LLFFFLFLFL

Sample Output

1 1 E
3 3 N LOST
2 3 S
 
出處: UVa Online Judge - Mutant Flatworld Explorers


問題敘述

此問題會先輸入兩個整數,表示這個矩形右上角的座標,接著會輸入多組測試資料,每組測試資料兩行,一直到輸入結束為止。每組測試資料第一行輸入的是兩個整數及一個字元,兩個整數代表機器人所在的初始的座標,字元表示面對的方位(E=東, W=西, S=南, N=北),第二行輸入的則是一行字串代表著一連串的指令(L=左轉, R=右轉, F=往現在面對的方位走一格)。每組輸入會對應一組輸出,此問題要求您輸出經過一連串的指令後,機器人最後所在的座標以及面對的方位為何。若機器人在執行指令的過程中跑出了此矩形的範圍,就輸出它在跑出去前的座標和方位並且印出 LOST,若機器人下次執行指令時,再次在之前跑出去過的座標往矩形外面跑,則此指令視為無效,將會被忽略。

解題思路

這是一個模擬類型的題目,沒有什麼特別的思路,但是要善用資料結構。比如說要如何知道左轉或右轉會轉到哪個方位呢? 我的作法是用一個陣列存{'E', 'N', 'W', 'S'},然後用一個 index 表示現在所在的位置,index + 1 就是左轉,index - 1 就是右轉,但是注意 index 做加減的時候可能會超出陣列範圍,所以要做環狀處理(意即 index 等於陣列的長度的時候要讓 index = 0,index 小於 0 的時候要讓 index = 陣列的長度 - 1)。其他的就把程式碼交給讀者們參考了。

c++ 程式碼

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

bool checkIsLost(int x, int y, int maxX, int maxY) {
    return x < 0 || x > maxX || y < 0 || y > maxY;
}

int main() {
    int maxX, maxY, x, y;
    char ori;
    string ins;
    char oriArr[4] = {'E', 'N', 'W', 'S'};
    int oriArrLen = 4;
    map<char, int> oriIndexMap;

    oriIndexMap['E'] = 0;
    oriIndexMap['N'] = 1;
    oriIndexMap['W'] = 2;
    oriIndexMap['S'] = 3;
    cin >> maxX >> maxY;
    vector< vector<bool> > lostTable(maxX + 1, vector<bool>(maxY + 1, false));
    while (cin >> x >> y >> ori >> ins) {
        int oriIndex;
        bool lost = false;

        oriIndex = oriIndexMap[ori];
        for (int i=0; i<ins.length(); i++) {
            switch (ins[i]) {
                case 'L':
                    oriIndex = (oriIndex + 1) % oriArrLen;
                    break;
                case 'R':
                    if (oriIndex)
                        oriIndex--;
                    else
                        oriIndex = oriArrLen - 1;
                    break;
                case 'F':
                    switch (oriIndex) {
                        case 0:
                            lost = checkIsLost(x + 1, y, maxX, maxY);
                            if (!lost)
                                x++;
                            break;
                        case 1:
                            lost = checkIsLost(x, y + 1, maxX, maxY);
                            if (!lost)
                                y++;
                            break;
                        case 2:
                            lost = checkIsLost(x - 1, y, maxX, maxY);
                            if (!lost)
                                x--;
                            break;
                        case 3:
                            lost = checkIsLost(x, y - 1, maxX, maxY);
                            if (!lost)
                                y--;
                    }
            }
            if (lost && !lostTable[x][y]) {
                lostTable[x][y] = true;
                break;
            }
        }
        cout << x << " " << y << " " << oriArr[oriIndex];
        if (lost)
            cout << " " << "LOST\n";
        else
            cout << endl;
    }

    return 0;
}

2014年4月7日 星期一

102 - Ecological Bin Packing

Background

Bin packing, or the placement of objects of certain weights into different bins subject to certain constraints, is an historically interesting problem. Some bin packing problems are NP-complete but are amenable to dynamic programming solutions or to approximately optimal heuristic solutions.
In this problem you will be solving a bin packing problem that deals with recycling glass.

The Problem

Recycling glass requires that the glass be separated by color into one of three categories: brown glass, green glass, and clear glass. In this problem you will be given three recycling bins, each containing a specified number of brown, green and clear bottles. In order to be recycled, the bottles will need to be moved so that each bin contains bottles of only one color.
The problem is to minimize the number of bottles that are moved. You may assume that the only problem is to minimize the number of movements between boxes.
For the purposes of this problem, each bin has infinite capacity and the only constraint is moving the bottles so that each bin contains bottles of a single color. The total number of bottles will never exceed 2^31.

The Input

The input consists of a series of lines with each line containing 9 integers. The first three integers on a line represent the number of brown, green, and clear bottles (respectively) in bin number 1, the second three represent the number of brown, green and clear bottles (respectively) in bin number 2, and the last three integers represent the number of brown, green, and clear bottles (respectively) in bin number 3. For example, the line 10 15 20 30 12 8 15 8 31
indicates that there are 20 clear bottles in bin 1, 12 green bottles in bin 2, and 15 brown bottles in bin 3.
Integers on a line will be separated by one or more spaces. Your program should process all lines in the input file.

The Output

For each line of input there will be one line of output indicating what color bottles go in what bin to minimize the number of bottle movements. You should also print the minimum number of bottle movements.
The output should consist of a string of the three upper case characters 'G', 'B', 'C' (representing the colors green, brown, and clear) representing the color associated with each bin.
The first character of the string represents the color associated with the first bin, the second character of the string represents the color associated with the second bin, and the third character represents the color associated with the third bin.
The integer indicating the minimum number of bottle movements should follow the string.
If more than one order of brown, green, and clear bins yields the minimum number of movements then the alphabetically first string representing a minimal configuration should be printed.

Sample Input

1 2 3 4 5 6 7 8 9
5 10 5 20 10 5 10 20 10

Sample Output

BCG 30
CBG 50

出處: UVa Online Judge - Ecological Bin Packing


問題敘述

此問題會有很多行輸入,每一行都會有九個整數,前三個整數分別代表在第一個回收桶裡棕色瓶子, 綠色瓶子和透明瓶子的數量,中間三個整數分別代表在第二個回收桶裡棕色瓶子, 綠色瓶子和透明瓶子的數量,最後三個整數分別代表在第三個回收桶裡棕色瓶子, 綠色瓶子和透明瓶子的數量。此問題要求您用最少的次數移動瓶子,來讓每個桶子都只裝一種顏色,並且輸出每個桶子各擺哪些顏色以及最少移動的次數。若不只一種移動方法可以讓每個桶子都只裝一種顏色且移動次數最少,則字母排列順序比較優先的要被輸出。

解題思路

因為瓶子的顏色只有三種,總共也只有六種排列方式,故暴力法是最簡單直接的解法。照字母順序把六種擺放瓶子顏色的方式都算出移動次數,並照順序找出移動次數最小的排列方式就是解答。

c++ 程式碼

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

int main() {
    int start;

    while (cin >> start) {
        vector< vector<int> > binBottle(3, vector<int>(3, -1));
        vector<string> comb(6, "");
        map<string, int> getCount;
        string minComb;

        comb[0] = "BCG";
        comb[1] = "BGC";
        comb[2] = "CBG";
        comb[3] = "CGB";
        comb[4] = "GBC";
        comb[5] = "GCB";
        for (int i=0; i<binBottle.size(); i++) {
            for (int j=0; j<binBottle[i].size(); j++) {
                if (!i && !j)
                    binBottle[i][j] = start;
                else
                    cin >> binBottle[i][j];
            }
        }
        getCount[comb[0]] = binBottle[1][0] + binBottle[2][0] + binBottle[0][2] + binBottle[2][2] +
                            binBottle[0][1] + binBottle[1][1];
        getCount[comb[1]] = binBottle[1][0] + binBottle[2][0] + binBottle[0][1] + binBottle[2][1] +
                            binBottle[0][2] + binBottle[1][2];
        getCount[comb[2]] = binBottle[1][2] + binBottle[2][2] + binBottle[0][0] + binBottle[2][0] +
                            binBottle[0][1] + binBottle[1][1];
        getCount[comb[3]] = binBottle[1][2] + binBottle[2][2] + binBottle[0][1] + binBottle[2][1] +
                            binBottle[0][0] + binBottle[1][0];
        getCount[comb[4]] = binBottle[1][1] + binBottle[2][1] + binBottle[0][0] + binBottle[2][0] +
                            binBottle[0][2] + binBottle[1][2];
        getCount[comb[5]] = binBottle[1][1] + binBottle[2][1] + binBottle[0][2] + binBottle[2][2] +
                            binBottle[0][0] + binBottle[1][0];
        minComb = comb[0];
        for (int i=1; i<comb.size(); i++) {
            if (getCount[minComb] > getCount[comb[i]])
                minComb = comb[i];
        }
        cout << minComb << " " << getCount[minComb] << endl;
    }

    return 0;
}

2014年2月8日 星期六

101 - The Blocks Problem


Background 

Many areas of Computer Science use simple, abstract domains for both analytical and empirical studies. For example, an early AI study of planning and robotics (STRIPS) used a block world in which a robot arm performed tasks involving the manipulation of blocks.
In this problem you will model a simple block world under certain rules and constraints. Rather than determine how to achieve a specified state, you will ``program'' a robotic arm to respond to a limited set of commands.

The Problem 

The problem is to parse a series of commands that instruct a robot arm in how to manipulate blocks that lie on a flat table. Initially there are nblocks on the table (numbered from 0 to n-1) with block bi adjacent to block bi+1 for all $0 \leq i < n-1$ as shown in the diagram below:

\begin{figure}
\centering
\setlength{\unitlength}{0.0125in} %
\begin{picture}
(2...
...raisebox{0pt}[0pt][0pt]{$\bullet
\bullet \bullet$ }}}
\end{picture}
\end{figure}
Figure: Initial Blocks World

The valid commands for the robot arm that manipulates blocks are:
  • move a onto bwhere a and b are block numbers, puts block a onto block b after returning any blocks that are stacked on top of blocks a and b to their initial positions.
  • move a over bwhere a and b are block numbers, puts block a onto the top of the stack containing block b, after returning any blocks that are stacked on top of block a to their initial positions.
  • pile a onto bwhere a and b are block numbers, moves the pile of blocks consisting of block a, and any blocks that are stacked above block a, onto block b. All blocks on top of block b are moved to their initial positions prior to the pile taking place. The blocks stacked above block aretain their order when moved.
  • pile a over bwhere a and b are block numbers, puts the pile of blocks consisting of block a, and any blocks that are stacked above block a, onto the top of the stack containing block b. The blocks stacked above block a retain their original order when moved.
  • quitterminates manipulations in the block world.
Any command in which a = b or in which a and b are in the same stack of blocks is an illegal command. All illegal commands should be ignored and should have no affect on the configuration of blocks.

The Input 

The input begins with an integer n on a line by itself representing the number of blocks in the block world. You may assume that 0 < n < 25.
The number of blocks is followed by a sequence of block commands, one command per line. Your program should process all commands until the quit command is encountered.
You may assume that all commands will be of the form specified above. There will be no syntactically incorrect commands.

The Output 

The output should consist of the final state of the blocks world. Each original block position numbered i ( $0 \leq i < n$ where n is the number of blocks) should appear followed immediately by a colon. If there is at least a block on it, the colon must be followed by one space, followed by a list of blocks that appear stacked in that position with each block number separated from other block numbers by a space. Don't put any trailing spaces on a line.
There should be one line of output for each block position (i.e., n lines of output where n is the integer on the first line of input).

Sample Input 

10
move 9 onto 1
move 8 over 1
move 7 over 1
move 6 over 1
pile 8 over 6
pile 8 over 5
move 2 over 1
move 4 over 9
quit

Sample Output 

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

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



問題敘述

此問題首先會輸入積木的個數,接著會輸入一連串的指令來告訴機器手臂該如何搬動積木,一直到輸入quit才結束。假設積木的總數量為n,積木會從0開始編號到n-1,指令的形式為: move/pile 積木編號 onto/over 積木編號,舉例: move 9 onto 1 意思就是把9號積木移動到1號積木的上面,若9號積木或1號積木上面有其他積木,就把上面的積木都移回原位。move 8 over 1 意思就是把8號積木移動到有1號積木的積木堆上面,若8號積木上面有其他積木,就把上面的積木都移回原位。pile 8 onto 6 意思就是把8號以上的積木全部移動到6號積木的上面,若6號積木上面有其他積木,就把上面的積木都移回原位。pile 8 over 6 意思就是把8號以上積木全部移動到有6號積木的積木堆上面。

解題思路

沒有什麼特別的思路,照著做就可以求解。不過在寫程式上卻有一些技巧,因為很多指令的動作是有重複的,所以可以把它寫成function呼叫。比如說"將某個積木上面的所有積木搬回原位"這個動作是很常用到的,所以可以寫成function比較方便。還有要注意的一點是如果指令裡的2個積木編號是在同一個積木堆上,則此指令無效,必須忽略此指令否則會wrong answer。

c++ 程式碼

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

void moveBackToOri(vector< vector<int> >& blocks, vector<int>& blockPos, int pos, int theBlock) {
    while (blocks[pos].back() != theBlock) {
        int last = blocks[pos].back();

        blocks[pos].pop_back();
        blocks[last].push_back(last);
        blockPos[last] = last;
    }
}

void pileBlocks(vector< vector<int> >& blocks, vector<int>& blockPos, int pos, int theBlock, vector<int>& temp) {
    while (true) {
        int last = blocks[pos].back();

        blocks[pos].pop_back();
        temp.push_back(last);
        if (last == theBlock)
            break;
    }
}

int main() {
    int blockNum;

    cin >> blockNum;
    vector< vector<int> > blocks(blockNum, vector<int>());
    vector<int> blockPos(blockNum, -1);
    for (int i=0; i<blocks.size(); i++) {
        blocks[i].push_back(i);
        blockPos[i] = i;
    }
    while (true) {
        string action, where;
        int fromBlock, toBlock;
        int fromPos;
        int toPos;

        cin >> action;
        if (action == "quit")
            break;
        cin >> fromBlock >> where >> toBlock;
        fromPos = blockPos[fromBlock];
        toPos = blockPos[toBlock];
        if (fromPos != toPos) {
            if (action == "move") {
                if (where == "onto") {
                    moveBackToOri(blocks, blockPos, fromPos, fromBlock);
                    moveBackToOri(blocks, blockPos, toPos, toBlock);
                    blocks[fromPos].pop_back();
                    blocks[toPos].push_back(fromBlock);
                    blockPos[fromBlock] = toPos;
                }
                else {
                    moveBackToOri(blocks, blockPos, fromPos, fromBlock);
                    blocks[fromPos].pop_back();
                    blocks[toPos].push_back(fromBlock);
                    blockPos[fromBlock] = toPos;
                }
            }
            else {
                vector<int> temp;

                if (where == "onto") {
                    pileBlocks(blocks, blockPos, fromPos, fromBlock, temp);
                    moveBackToOri(blocks, blockPos, toPos, toBlock);
                    while (!temp.empty()) {
                        int last = temp.back();

                        temp.pop_back();
                        blocks[toPos].push_back(last);
                        blockPos[last] = toPos;
                    }
                }
                else {
                    pileBlocks(blocks, blockPos, fromPos, fromBlock, temp);
                    while (!temp.empty()) {
                        int last = temp.back();

                        temp.pop_back();
                        blocks[toPos].push_back(last);
                        blockPos[last] = toPos;
                    }
                }
            }
        }
    }
    for (int i=0; i<blocks.size(); i++) {
        cout << i << ":";
        for (int j=0; j<blocks[i].size(); j++)
            cout << " " << blocks[i][j];
        cout << endl;
    }

    return 0;
}

2014年2月1日 星期六

105 - The Skyline Problem



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


問題敘述

此問題會輸入很多組長方形建築物的資料,每組資料分別是: 左x座標, 高度, 右x座標,輸入資料會照著左x座標由小到大排序,得到所有建築物的資料之後,必須輸出"天際線向量"。所謂天際線向量,就是用一個長的像這樣子的向量: (v1, v2, v3, ... , vn) 來表示天際線,奇數位置填的是x座標,偶數位置填的是高度,必須從最小的x座標開始填起。

解題思路

這題有一個可以減少我們很多功夫的關鍵點,那就是所有座標都是小於10,000的整數,也就是說我們只要開一個10,000個元素的陣列,暴力記下每一個x座標的最高點,就可以完成天際線向量了。所以此題的演算法大致上是如此: 每讀入一組建築物資料,就更新那一區塊的所有x座標的最高點(注意不要更新到建築物最右邊座標的高度,因為這樣才能知道哪個x座標開始產生高度變化),最後只要從小到大把每個x座標的最高點掃描一遍,就可以印出天際線向量了。

c++ 程式碼

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

int main() {
    int left, right, height, last;
    int first = -1;
    int nowHeight = 0;
    vector<int> heightVec(10000, 0);

    while (cin >> left >> height >> right) {
        if (first == -1) {
            first = left;
            last = right;
        }
        if (right > last)
            last = right;
        for (int i=left; i<right; i++) {
            if (height > heightVec[i])
                heightVec[i] = height;
        }
    }
    for (int i=first; i<=last; i++) {
        if (heightVec[i] != nowHeight) {
            cout << i << " " << heightVec[i];
            if (i == last)
                cout << endl;
            else {
                cout << " ";
                nowHeight = heightVec[i];
            }
        }
    }

    return 0;
}

2013年9月2日 星期一

104 - Arbitrage

Background

The use of computers in the finance industry has been marked with controversy lately as programmed trading -- designed to take advantage of extremely small fluctuations in prices -- has been outlawed at many Wall Street firms. The ethics of computer programming is a fledgling field with many thorny issues.

The Problem

Arbitrage is the trading of one currency for another with the hopes of taking advantage of small differences in conversion rates among several currencies in order to achieve a profit. For example, if $1.00 in U.S. currency buys 0.7 British pounds currency, £1 in British currency buys 9.5 French francs, and 1 French franc buys 0.16 in U.S. dollars, then an arbitrage trader can start with $1.00 and earntex2html_wrap_inline29 dollars thus earning a profit of 6.4 percent.
You will write a program that determines whether a sequence of currency exchanges can yield a profit as described above.
To result in successful arbitrage, a sequence of exchanges must begin and end with the same currency, but any starting currency may be considered.

The Input

The input file consists of one or more conversion tables. You must solve the arbitrage problem for each of the tables in the input file.
Each table is preceded by an integer n on a line by itself giving the dimensions of the table. The maximum dimension is 20; the minimum dimension is 2.
The table then follows in row major order but with the diagonal elements of the table missing (these are assumed to have value 1.0). Thus the first row of the table represents the conversion rates between country 1 and n-1 other countries, i.e., the amount of currency of country i ( tex2html_wrap_inline37 ) that can be purchased with one unit of the currency of country 1.
Thus each table consists of n+1 lines in the input file: 1 line containing n and n lines representing the conversion table.

The Output

For each table in the input file you must determine whether a sequence of exchanges exists that results in a profit of more than 1 percent (0.01). If a sequence exists you must print the sequence of exchanges that results in a profit. If there is more than one sequence that results in a profit of more than 1 percent you must print a sequence of minimal length, i.e., one of the sequences that uses the fewest exchanges of currencies to yield a profit.

Because the IRS (United States Internal Revenue Service) notices lengthy transaction sequences, all profiting sequences must consist of n or fewer transactions where n is the dimension of the table giving conversion rates. The sequence 1 2 1 represents two conversions.
If a profiting sequence exists you must print the sequence of exchanges that results in a profit. The sequence is printed as a sequence of integers with the integer i representing the tex2html_wrap_inline51 line of the conversion table (country i). The first integer in the sequence is the country from which the profiting sequence starts. This integer also ends the sequence.
If no profiting sequence of n or fewer transactions exists, then the line
no arbitrage sequence exists
should be printed.

Sample Input


3
1.2 .89
.88 5.1
1.1 0.15
4
3.1    0.0023    0.35
0.21   0.00353   8.13 
200    180.559   10.339
2.11   0.089     0.06111
2
2.0
0.45

Sample Output


1 2 1
1 2 4 1
no arbitrage sequence exists

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


問題敘述

此問題首先會輸入國家的數量,並且輸入每個國家和每個國家的匯率兌換表(同個國家的兌換匯率不會輸入,因為一定是1),要您求出可以經由最少的兌換次數來達到獲利超過1%的兌換方式(可以在任何國家的幣紙上獲利),若有兩種以上最少兌換次數可以獲利超過1%,隨便印出一種兌換方法即可,若找不到兌換方法,則印出"no arbitrage sequence exists"。

解題思路

此題使用Dynamic programming來解,首先求出各個國家只兌換1次可以得到的最佳解(也就是初始的匯率兌換表),再利用只兌換1次的最佳解求出只兌換2次的最佳解,接著再利用只兌換2次的最佳解求出只兌換3次的最佳解...依此類推,一直求到有國家自己兌換自己可以超過1.01就表示找到解了,若一直求到n次兌換都找不到解,表示此解找不到。

c++ 程式碼

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

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

int main() {
    int countryNum;

    while (cin >> countryNum) {
         vector< vector< vector<double> > > bestRateEachStep(countryNum, vector< vector<double> >(countryNum,
                      vector<double>(countryNum, 0)));
         vector< vector< vector<int> > > path(countryNum, vector< vector<int> >(countryNum,
                      vector<int>(countryNum, -1)));
         int startCountry = -1;
         int lastStep = -1;

        for (int i=0; i<countryNum; i++) {
            for (int j=0; j<countryNum; j++) {
                if (i == j)
                    bestRateEachStep[0][i][j] = 1;
                else
                    cin >> bestRateEachStep[0][i][j];
            }
        }
        for (int step=1; step<countryNum; step++) {
            for (int k=0; k<countryNum; k++) {
                for (int i=0; i<countryNum; i++) {
                    for (int j=0; j<countryNum; j++) {
                        if (bestRateEachStep[step - 1][i][k] * bestRateEachStep[0][k][j] > bestRateEachStep[step][i][j]) {
                            bestRateEachStep[step][i][j] = bestRateEachStep[step - 1][i][k] * bestRateEachStep[0][k][j];
                            path[step][i][j] = k;
                        }
                    }
                }
            }
            for (int i=0; i<countryNum; i++) {
                if (bestRateEachStep[step][i][i] > 1.01) {
                    startCountry = i;
                    lastStep = step;
                    break;
                }
            }
            if (startCountry != -1)
                break;
        }
        if (startCountry == -1)
            cout << "no arbitrage sequence exists\n";
        else {
            cout << startCountry + 1;
            findPath(path, startCountry, startCountry, lastStep);
            cout << " " << startCountry + 1 << endl;
        }
    }

    return 0;
}

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;
}

2013年5月6日 星期一

10156 - Sala-ma-Sond, A Nice Little Pond


The Problem

Of course, the turtles aren't completely free. In particular, they aren't free to swim where other turtles are swimming. To learn more about the swimming behaviour of turtles you decide to write a computer simulation of a pond and the turtles swimming in it.
For simplicity, you represent the pond as a rectangular grid, with turtles occupying positions at points on the grid. If the pond is an NxM grid, a position on the grid may be represented by a pair of integer coordinates (i, j), with 0 <= i < N and 0 <= j < M. The grid is aligned with its first dimension running north-south and its second dimension running east-west. Coordinate values increase to the south and the east.
A turtle swimming in the pond may be requested to move to the adjacent grid position in one of eight directions: N, S, E, W, NE, NW, SE, SW. If the request would cause the turtle to move off the grid or cause it to move onto a grid position occupied by another turtle, the request is ignored. Otherwise, the turtle happily obeys the movement request. (Turtles are easy to push around.)
The input consist of several data sets. Each data set begins with a description of the pond and the initial location of the turtles. The first line of the input consists of four integers separated by one or more spaces. The first integer specifies the size of the pond in the north-south direction (N), the second integer specifies the size of the pond in the east-west direction (M), the third integer specifies the number of turtles in the pond (T) and the fourth integer indicates the number of turtle movement requests (K). This first line is followed by T lines, each providing information on a single turtle. Each line of turtle information consists of three integers separated by one or more spaces. The first integer specifies a turtle id, the second integer specifies an initial grid position for the turtle along the north-south dimension, and the third integer specifies an initial grid position for the turtle along the east-west dimension. All turtles will be located at valid grid positions; no two turtles will be located at the same grid position; turtle ids are in the range one to ten thousand; the maximum size of the grid in either dimension is sixty; the minimum size is two.
Following the description of the pond and its initial turtle configuration, the remainder of the input, consists of a sequence of K turtle movement requests, one per line. Each movement request consists of a turtle id followed by a movement direction, and indicates that the specified turtle should be requested to move one grid position in the specified direction. The turtle id and movement direction are separated by one or more spaces. The movement direction is one of: `N', `S', `E', `W', `NE', `NW', `SE', `SW'. The turtle requests should be processed sequentially starting from the initial pond configuration given in the input.
The output is a graphical representation of the pond configuration for each data set after all turtle movement requests have been processed. A picture of the pond is rendered using ASCII characters. Beginning with the most northerly row, each row of the grid is represented by a single line in the output. Grid positions along a row are represented by character positions in the output line. The final position of a turtle is marked with an asterisk (`*'); space characters are used to fill empty grid positions. If the output is displayed as text on a computer screen or printed page, the result is a map of turtle positions in the pond, with north toward the top, east toward the right, and west toward the left. Spaces should be generated only when required for positioning turtles; output lines should not have trailing spaces. Print a blank line after each data set.

Sample Input

4 4 3 4
1 0 0
2 0 2
3 3 3
1 S
2 W
2 W
1 SE
4 4 3 4
1 0 0
2 0 2
3 3 3
2 W
2 W
1 S
1 SW

Sample Output

*

 *
   *

 *
*

   *

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

這一題基本上就是照著題目做就對了,不過要注意移動烏龜的時候不能超出池塘的範圍或是撞到別的烏龜(也就是兩個烏龜不能在同一個位置),如果有以上違反規定的移動出現就要忽略。

以下是c++程式碼:

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

typedef map<int, int> colMap;
struct position {
    int x, y;
};

int main() {
    int row, col, turNum, req;

    while (cin >> row >> col >> turNum >> req) {
        map<int, struct position> findTur;
        map<int, colMap> pool;
        map<int, int> rowMax;
        struct position pos[turNum];

        for (int i=0; i<turNum; i++) {
            int turId, x, y;

            cin >> turId >> x >> y;
            pos[i].x = x;
            pos[i].y = y;
            findTur[turId] = pos[i];
            pool[x][y] = turId;
        }
        for (int i=0; i<req; i++) {
            int turId, x, y;
            string dir;

            cin >> turId >> dir;
            x = findTur[turId].x;
            y = findTur[turId].y;
            pool[x][y] = 0;
            if (dir == "N")
                x--;
            else if (dir == "S")
                x++;
            else if (dir == "E")
                y++;
            else if (dir == "W")
                y--;
            else if (dir == "NE") {
                x--;
                y++;
            }
            else if (dir == "NW") {
                x--;
                y--;
            }
            else if (dir == "SE") {
                x++;
                y++;
            }
            else if (dir == "SW") {
                x++;
                y--;
            }
            if (x >= 0 && y >= 0 && x < row && y < col && pool[x][y] == 0) {
                findTur[turId].x = x;
                findTur[turId].y = y;
                pool[x][y] = turId;
            }
            else
                pool[findTur[turId].x][findTur[turId].y] = turId;
        }
        for (int i=0; i<row; i++) {
            int j;

            for (j=col-1; j>=0 && pool[i][j]==0; j--);
            rowMax[i] = j;
        }
        for (int i=0; i<row; i++) {
            for (int j=0; j<=rowMax[i]; j++) {
                if (pool[i][j])
                    cout << '*';
                else
                    cout << ' ';
            }
            cout << endl;
        }
        cout << endl;
    }

    return 0;
}

10101 - Bangla Numbers


Bangla numbers normally use 'kuti' (10000000), 'lakh' (100000), 'hajar' (1000), 'shata' (100) while expanding and converting to text. You are going to write a program to convert a given number to text with them.

Input
The input file may contain several test cases. Each case will contain a non-negative number <= 999999999999999.

Output
For each case of input, you have to output a line starting with the case number with four digits adjustment followed by the converted text.

Sample Input

23764
45897458973958

Sample Output

   1. 23 hajar 7 shata 64
   2. 45 lakh 89 hajar 7 shata 45 kuti 89 lakh 73 hajar 9 shata 58




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


這題就是把數字代進去遞迴求解即可。比較需要注意的是input數字可能會很大,所以我使用long long 資料型態,以及要考慮到input是0的情況,最後注意到output開頭的case數字格式是有特別規範的,需要4個格子並且靠右輸出。

以下是c++程式碼:

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

void bangla(long long num) {
    if (num >= 10000000) {
        bangla(num / 10000000);
        cout << " kuti";
        num %= 10000000;
    }
    if (num >= 100000) {
        bangla(num / 100000);
        cout << " lakh";
        num %= 100000;
    }
    if (num >= 1000) {
        bangla(num / 1000);
        cout << " hajar";
        num %= 1000;
    }
    if (num >= 100) {
        bangla(num / 100);
        cout << " shata";
        num %= 100;
    }
    if (num)
        cout << " " << num;
}

int main() {
    long long num;
    long long countCase = 0;

    while (cin >> num) {
        cout << setw(4) << right << ++countCase << ".";
        if (num)
            bangla(num);
        else
            cout << " 0";
        cout << endl;
    }

    return 0;
}

2013年4月29日 星期一

10093 - An Easy Problem!


Have you heard the fact “The base of every normal number system is 10” ? Of course, I am not talking about number systems like Stern Brockot Number System. This problem has nothing to do with this fact but may have some similarity.  

You will be given an N based integer number R and you are given the guaranty that R is divisible by (N-1). You will have to print the smallest possible value for N. The range for N is 2<=N<=62 and the digit symbols for 62 based number is (0..9 and A..Z and a..z). Similarly, the digit symbols for 61 based number system is (0..9 and A..Z and a..y) and so on.  

Input
Each line in the input file will contain an integer (as defined in mathematics) number of any integer base (2..62). You will have to determine what is the smallest possible base of that number for the given conditions. No invalid number will be given as input.

Output
If number with such condition is not possible output the line “such number is impossible!” For each line of input there will be only a single line of output. The output will always be in decimal number system.

Sample Input
3
5
A

Sample Output
4
6
11


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


這題可能需要知道一個定理會簡單得多,若一個n進位的數可以被n - 1整除,則它每個位數的總和也會被n - 1整除。題目要求找到最小的n,所以我們可以先找到最小的n - 1,這樣就可以找到最小的n。因為n - 1最小要和所有位數裡最大的數相等,所以可以把所有位數裡面最大的數當作找n - 1的起點,接著把61(因為題目說進位最大只到62進位)當作終點,只要一有可以整除所有位數總和的數字出現,它就是最小的n - 1。

c++程式碼:

#include <iostream>
using namespace std;

int main() {
    string input;

    while (cin >> input) {
        int digitSum = 0;
        int ans = -1;
        int maxDigit = -1;

        for (int i=0; i<input.length(); i++){
            int thisDigit;

            if (input[i] >= 'A' && input[i] <= 'Z')
                thisDigit = input[i] - 'A' + 10;
            else if (input[i] >= 'a' && input[i] <= 'z')
                thisDigit = input[i] - 'a' + 36;
            else if (input[i] >= '0' && input[i] <= '9')
                thisDigit = input[i] - '0';
            else
                continue;
            if (thisDigit > maxDigit)
                maxDigit = thisDigit;
            digitSum += thisDigit;
        }
        if (!maxDigit)
            maxDigit = 1;
        for (int i=maxDigit; i<=61; i++) {
            if (!(digitSum % i)) {
                ans = i + 1;
                break;
            }
        }
        if (ans == -1)
            cout << "such number is impossible!\n";
        else
            cout << ans << endl;
    }

    return 0;
}