题意:
嵌套玩具, 要求外层玩具的尺寸比内层玩具尺寸的和要大. 每一个玩具由一个负数与相应的正数表示, 在这两数之间的部分即为此玩具内部的玩具. 要求判断一串输出的数字是否能组成一个合法的玩具. 一个合法的玩具:
1. 数字代表了 toy 的尺寸大小.
2. 外层的 size 必须 > 内层 size 的和, 不能是 >=.
3. 每次必须是负正对一起出现.
思路:
1. 使用 vector 存放所有输入的数字, list 从尾至头表示已处理过的玩具.
2. 每次从头到尾遍历 vector, 碰到负数, 就依次添加到 list 的首部.
3. 当 vector 碰到一个正数时, 就从 list 的首部向尾查找, 找到第一个负数, 若能找到, 且这个负数与正数是匹配的, 则这是一个玩具.
4. 计算 list 首至负数之间的正数和是否小于当前正数, 若小于, 说明此玩具是合法的, 接着把 list 首至负数之间的所有正数都删掉, 替换成刚才碰到的正数.
5. 即当一个玩具匹配完后, 就只是保存其最外层的数据, 而不再考虑其内部包含的其他玩具.
6. 最后 list 中存放的应该是所有已处理好的玩具.
要点:
1. 用 istringstream 从 string 中读取整数.
题目:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=103&page=show_problem&problem=2052
代码:
# include <iostream> # include <string> # include <cstdio> # include <cstring> # include <vector> # include <algorithm> # include <cctype> # include <iterator> # include <assert.h> # include <sstream> // istringstream # include <list> using namespace std; typedef list<int>::const_iterator LCIT; typedef list<int>::iterator LIT; // 添加一个新的 matrioshka, 即把从 [begin, end) 之间的数都去掉, 然后新增一个 k void addNewMatrioshka(list<int>& matrioshka, LIT end, int k) { matrioshka.erase(matrioshka.begin(), end); matrioshka.push_front(k); } // 返回链表中从头至尾第一个负数 LIT getFirstNegative(list<int>& matrioshka) { LIT it; for (it = matrioshka.begin(); it != matrioshka.end(); it++) { if (*it < 0) break; } return it; } // 判断新得到的 matrioshka 是否是有效的, 即要使当前数与 k 互为正负 // 且要使 [begin, end]) 之间的正数和小于 k bool isMatrioshkaValid(const list<int>& matrioshka, LCIT end, int k) { if (*end != (-1*k)) return false; int size = 0; for (LCIT it = matrioshka.begin(); it != end; it++) { assert (*it > 0); size += *it; } return (size < k); } // 判断是否为一个合法的玩具 bool isMatrioshka(const vector<int>& sizes) { list<int> matrioshka; for (int i=0; i<sizes.size(); i++) { if (sizes[i] < 0) { matrioshka.push_front(sizes[i]); } else { LIT it = getFirstNegative(matrioshka); if (it != matrioshka.end() && isMatrioshkaValid(matrioshka, it, sizes[i])) { addNewMatrioshka(matrioshka, ++it, sizes[i]); } else { return false; } } } // 最后应该都是正数, 因为一行中可能会包含多个 toys if (!matrioshka.empty()) { for (LCIT it = matrioshka.begin(); it != matrioshka.end(); it++) { if (*it < 0) return false; } return true; } return false; } int main(int argc, char const *argv[]) { #ifndef ONLINE_JUDGE freopen("11111_i.txt", "r", stdin); freopen("uva_o.txt", "w", stdout); #endif string line; while (getline(cin, line)) { istringstream iss(line); vector<int> sizes; int k; while (iss >> k) { sizes.push_back(k); } if (isMatrioshka(sizes)) { cout << ":-) Matrioshka!" << endl; } else { cout << ":-( Try again." << endl; } } /* 此题如果按以下形式读取,就总会报 WA,为什么??? 最后的空行会输出文字,而不是答案需要的 不处理!!! string line; while (!cin.eof()) { getline(cin, line); istringstream iss(line); vector<int> sizes; while (!iss.eof()) { int k; iss >> k; sizes.push_back(k); } ... } */ return 0; }
环境: C++ 4.5.3 - GNU C++ Compiler with options: -lm -lcrypt -O2 -pipe -DONLINE_JUDGE
参考: 这里用栈来解, 解法很不错 http://www.cppblog.com/rakerichard/archive/2011/04/14/144183.html