前言
这题题目实在有够长,光题目我就看了非常久,题目看不懂真的很惨连做都没办法做(翻译我也看不懂,中英文都很差真的很惨..),还好最后多亏这位大大的文章和测试工具的帮忙才了解题目....。
原题目
题目
Code Jam团队买了一个果园,他刚好是一个二维矩阵1000行和1000列,计画用来种植各种树木。
我们至少要有一个準备好的位置。所有準备好的位置都必须组成一个对齐的矩形,矩形中每个位置也必须準备好。注意,上述还包括已準备好的位置不能超过该矩形之外。
例如(*为準备好位置, .为未準备好位置):
当A = 11,如图一虽然他面积是11但矩形内有一个未準备,那这个果园就不算是準备好,必须和图二一样整个矩形都準备好。
******.********图一
***************图二
当A = 6,如图三很明显未準备好,图四虽然有6块但它不是一个完整的矩形,图五虽然有一个完整矩形但它周围多出一块已準备好,所以这些果园都未準备好。
**.***图三
.***.*.**图四
.*****.**图五
我们借用了Go gopher,指定位置来帮助我们,但我们还没有完善的开发,目前只可以在指定位置为中心3X3区块中随机準备好一个位置。
我们只能使用1000次来完成我们的果园。
输入输出
这题是互动式题目,官方提供了下载Python脚本来进行测试,输入整数T表示测试数量,A为矩形面积,最多只能互动1000次。
你的程式必须输出i和j位置(中心位置),并介于2~999之间,如果格式错误将会读取到-1 -1已準备好位置。为了要回应请将程式使用标準输入读取回传已準备好数值。
当你完成矩形则会接收到0 0位置,然后就停止输入输出,若程式还在等待则会判断为超时。
範围
1 ≤ T ≤ 20.
记忆体: 1 GB.
测试1:
A = 20.
时间限制: 20 秒.
测试2:
A = 200.
时间限制: 60 秒.
範例
t = readline_int() // 读取T测资数量
a = readline_int() // 读取A面积
printline 10 10 to stdout // 输出10 10位置
flush stdout
x, y = readline_two_int() // 读取到已準备好位置10 11
printline 10 10 to stdout // 输出10 10位置
flush stdout
x, y = readline_two_int() // 读取到已準备好位置10 10
printline 10 12 to stdout // 输出10 12位置
flush stdout
x, y = readline_two_int() // 读取到已準备好位置10 11
printline 10 10 to stdout // 输出10 10位置
flush stdout
x, y = readline_two_int() // 读取到已準备好位置11 10
printline 11 10 to stdout // 输出11 10位置
flush stdout
x, y = readline_two_int() // 读取到0 0,已完成面积矩形
解析
当下看到题目非常之长,最后才发现其实就只是要你在1000次内把指定面积矩形做出来就好,测试固定20和200那问题就简单许多了。
Go Gopher是随机我们输出的位置当中心来回传的,那我们就可以先把固定一块Block(3X3)填满再去填满下一块,因为最大200块也不用担心会超出範围。测试工具
Windows cmd:testing_tool.py ./Console.exe
如果运行过会这样
完整程式码
#include <iostream>#include <string>#include <vector>using namespace std;const int MAX = 1000;void Process(const int& blockSize){vector<int> blockUsed(blockSize, 0);vector<vector<vector<bool>>> check(blockSize, vector<vector<bool>>(3, vector<bool>(3, true)));int index = 0;int count = 0;int centerX = 3;int centerY = 3;int x = 0;int y = 0;while (count < MAX) {cout << centerX << " " << centerY << endl;cin >> x >> y;if ((x == 0 && y == 0)){return;}const int offsetX = x - centerX + 1;const int offsetY = y - centerY + 1;if (check[index][offsetX][offsetY]){blockUsed[index] += 1;check[index][offsetX][offsetY] = false;}if (blockUsed[index] == 9){index++;centerX += 3;}count++;}}void Input(){int count = 0;if (cin >> count){for (int index = 0; index < count; index++){int area = 0;cin >> area;const int blockSize = (area / 9) + ((area % 9) == 0 ? 0 : 1);Process(blockSize);}}}int main(){Input();return 0;}
程式码解析
输入
1.count 测资数量。
2.area 面积。
3.blockSize 3X3的Block数量。
4.Process 运行交互式函数。
5.开始交换讯息。
void Input(){int count = 0;if (cin >> count){for (int index = 0; index < count; index++){int area = 0;cin >> area;const int blockSize = (area / 9) + ((area % 9) == 0 ? 0 : 1);Process(blockSize);}}}
运行
1.我们先宣告一个容器blockUsed来记录準备好的数量,和一个容器check来纪录已準备好的位置(都是3X3当作一个index)。
2.index记录目前Block位置,count来记录交换次数(最大1000)。
3.我选择从centerX = 3,centerY = 3当第一个Block的中心。
4.x和y则是要接收Go Gopher回传已準备好的位置。
void Process(const int& blockSize){vector<int> blockUsed(blockSize, 0);vector<vector<vector<bool>>> check(blockSize, vector<vector<bool>>(3, vector<bool>(3, true)));int index = 0;int count = 0;int centerX = 3;int centerY = 3;int x = 0;int y = 0;while (count < MAX) {cout << centerX << " " << centerY << endl;cin >> x >> y; // 如果已完成则退出if ((x == 0 && y == 0)){return;} // 计算容器位置(可改为宣告1000 * 1000则不用计算)const int offsetX = x - centerX + 1;const int offsetY = y - centerY + 1; // 如果未使用,Block数量加一和设定已使用if (check[index][offsetX][offsetY]){blockUsed[index] += 1;check[index][offsetX][offsetY] = false;} // 当下Block已準备好,换下一块if (blockUsed[index] == 9){index++;centerX += 3;}count++;}}
结语
这次改了一下解释风格,但还是有部分式写在里面,会慢慢改善排版模式让人轻鬆观看。