PC/UVa:110902/10067
- 最开始以为这齿轮动一个其它的也跟着动,所以
8个按钮其实只有2个按钮有用,但是后来从一些测试用例来看,齿轮之间不存在传动 - 我严格按照题目中描述的输入数据格式处理输入,把每一行先读入,然后再解析每一行的内容,结果就Runtime Error了,最开始以为是标志位开的太大了,后来拿到Ubuntu上试了下,误输入的时候会出现
stoul异常,所以改成了全部按int读取,这才AC。 - C++中的
stoul函数中输入的字符串无法转换为时整数时就会出现异常退出,感觉这个函数还是要少使用,或者在转换之前应该检查一下。 - 有时uDebug上的测试用例跑太长是因为输入数据量太大了,并不是算法的原因
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <queue>
using namespace std;
struct Node
{
typedef Node(Node::*TransFunc)(int pos);
static const vector<int> viBase;
string strState;
int iState;
int step;
Node() = default;
Node(const string &strState, const int step)
:strState(strState), iState(stoul(strState)), step(step){}
Node leftBtn(int pos);
Node rightBtn(int pos);
};
const vector<int> Node::viBase = { 1000, 100, 10, 1 };
Node Node::leftBtn(int pos)
{
Node ret(strState, step + 1);
if (ret.strState[pos] == '0'){
ret.strState[pos] = '9';
ret.iState += 9 * viBase[pos];
}
else{
ret.strState[pos] -= 1;
ret.iState -= viBase[pos];
}
//ret.iState = stoul(ret.strState);
return ret;
}
Node Node::rightBtn(int pos)
{
Node ret(strState, step + 1);
ret.step = step + 1;
ret.strState.assign(strState);
if (ret.strState[pos] == '9'){
ret.strState[pos] = '0';
ret.iState -= 9 * viBase[pos];
}
else{
ret.strState[pos] += 1;
ret.iState += viBase[pos];
}
//ret.iState = stoul(ret.strState);
return ret;
}
void BFS(const string &strInit, const string &strFinal,
const vector<bool> &vbForbidding)
{
vector<Node::TransFunc> vecTrans;
vecTrans.push_back(&Node::leftBtn);
vecTrans.push_back(&Node::rightBtn);
vector<bool> vbVisit(10000, false);
queue<Node> qNode;
Node node(strInit, 0), curr, fin(strFinal, -1);
qNode.push(node);
vbVisit[node.iState] = true;
bool bFind = false;
if (node.iState == fin.iState) bFind = true;
else if (vbForbidding[fin.iState]) bFind = false;
else{
while (!qNode.empty()){
curr = qNode.front();
qNode.pop();
for (int pos = 0; pos < 4; pos++)
{
for (size_t i = 0; i < vecTrans.size(); i++)
{
node = (curr.*vecTrans[i])(pos);
if (node.iState == fin.iState){
bFind = true;
break;
}
if (!vbVisit[node.iState] && !vbForbidding[node.iState]){
qNode.push(node);
vbVisit[node.iState] = true;
}
}
}
if (bFind) break;
}
}
if (bFind){
cout << node.step << endl;
}
else cout << -1 << endl;
}
int main()
{
int T = 0;
cin >> T;
for (int t = 0; t < T; t++)
{
string strInit, strFinal;
int i = 0, n = 0;
for(int idx = 0; idx < 4;idx++)
{
cin >> i;
strInit.push_back(i + '0');
}
for (int idx = 0; idx < 4; idx++)
{
cin >> i;
strFinal.push_back(i + '0');
}
vector<bool> viForbidding(10000, false);
cin >> n;
while (n-- > 0){
int s = 0;
for (int idx = 0; idx < 4; idx++)
{
cin >> i;
s *= 10;
s += i;
}
viForbidding[s] = true;
}
BFS(strInit, strFinal, viForbidding);
}
return 0;
}
/*
2
8 0 5 6
6 5 0 8
5
8 0 5 7
8 0 4 7
5 5 0 8
7 5 0 8
6 4 0 8
0 0 0 0
5 3 1 7
8
0 0 0 1
0 0 0 9
0 0 1 0
0 0 9 0
0 1 0 0
0 9 0 0
1 0 0 0
9 0 0 0
*/
本文分享了解决PC/UVa 110902/10067号问题Playing with Wheels的编程经验。作者最初误解了题目的齿轮联动机制,后发现齿轮间并无直接联系。通过改进输入处理方式,避免stoul异常,最终实现BFS算法求解。文章揭示了正确处理输入数据格式的重要性。

被折叠的 条评论
为什么被折叠?



