UVA 101积木问题提交报运行时错误,VS Code本地运行正常
UVA 101 积木问题运行时错误排查建议
我在解决UVA 101 The Blocks Problem时,用C++写的代码在VS Code里跑样例输入能得到正确输出,但提交到UVA平台出现运行时错误。我严格遵循了问题描述的所有要求,请求提供解决该错误的建议。
以下是我的代码:
#include<iostream> #include<string.h> #include<vector> #include<algorithm> using namespace std; void returnAllPos(int x, vector<vector<int>> &blocks){ while(blocks[x].back() != x){ int idx = blocks[x].back(); blocks[x].pop_back(); if(blocks[idx].size() == 0){ blocks[idx].push_back(idx); } else{ returnAllPos(idx, blocks); } } } void outputBlocks(vector<vector<int>> &blocks){ for(int i = 0; i < blocks.size(); i++){ cout << i << ":"; for(int j = 0; j < blocks[i].size(); j++){ cout << " " << blocks[i][j]; } cout << '\n'; } } void onto(int a, int b, vector<vector<int>> &blocks){ returnAllPos(a, blocks); returnAllPos(b, blocks); blocks[b].push_back(a); blocks[a].pop_back(); } void over(int a, int b, vector<vector<int>> &blocks){ returnAllPos(a, blocks); // find B and put a on top for(int i = 0; i < blocks.size(); i++){ if(find(blocks[i].begin(), blocks[i].end(), b) != blocks[i].end()){ blocks[i].push_back(blocks[a].back()); blocks[a].pop_back(); } } } bool samestack(int a, int b, vector<vector<int>> &blocks){ for(int i = 0; i < blocks.size(); i++){ if(find(blocks[i].begin(), blocks[i].end(), b) != blocks[i].end() && find(blocks[i].begin(), blocks[i].end(), a) != blocks[i].end()){ return true; } } return false; } void pileover(int a, int b, vector<vector<int>> &blocks){ for(int i = 0; i < blocks.size(); i++){ for(int j = 0; j < blocks[i].size(); j++){ if(blocks[i][j] == a){ int end = blocks[i].back(); std::reverse((blocks[i].begin() + j), blocks[i].end()); while(1){ int elem = blocks[i].back(); blocks[i].pop_back(); blocks[b].push_back(elem); if(elem == end) return; } } } } } void pileonto(int a, int b, vector<vector<int>> &blocks){ returnAllPos(b, blocks); pileover(a, b, blocks); } int main(void){ int size = 0; cin >> size; // read the first line if(size < 1 || size > 25) return 1; vector<vector<int>> blocks(size); for(int i = 0; i < size; i++){ blocks[i].push_back(i); } std::string first, second; int a, b; while(1){ cin >> first; if(first == "quit") break; cin >> a >> second >> b; if(samestack(a, b, blocks) || a == b) continue; if((a >= 0 && b >= 0) && (a < size && b < size)){ if(first == "pile"){ if(second == "onto"){ pileonto(a, b, blocks); } else if(second == "over"){ pileover(a, b, blocks); } } else if(first == "move"){ if(second == "over") over(a, b, blocks); else if(second == "onto") onto(a, b, blocks); } } } outputBlocks(blocks); return 0; }
错误排查与修正建议
核心错误:混淆积木编号与栈索引
代码中多处直接用积木编号作为栈的索引(如blocks[x]),但积木被移动后,其所在的栈并非blocks[x]。当积木不在初始栈时,blocks[x]可能为空,此时访问blocks[x].back()会触发空容器访问的运行时错误,这是导致UVA提交崩溃的主要原因。修正
returnAllPos函数
该函数的正确逻辑是先找到积木x所在的栈,再将x上方的所有积木放回各自的初始栈。示例修正:void returnAllPos(int x, vector<vector<int>> &blocks) { int stackIdx = -1; int pos = -1; // 找到x所在的栈和位置 for (int i = 0; i < blocks.size(); ++i) { auto it = find(blocks[i].begin(), blocks[i].end(), x); if (it != blocks[i].end()) { stackIdx = i; pos = it - blocks[i].begin(); break; } } if (stackIdx == -1) return; // 将x上方的积木放回各自初始栈 for (int i = blocks[stackIdx].size() - 1; i > pos; --i) { int elem = blocks[stackIdx][i]; blocks[stackIdx].pop_back(); blocks[elem].push_back(elem); } }修正
onto函数
原函数直接操作blocks[a]和blocks[b]是错误的,需先找到a、b所在的栈再进行操作:void onto(int a, int b, vector<vector<int>> &blocks) { returnAllPos(a, blocks); returnAllPos(b, blocks); int aStack = -1, bStack = -1; // 找到a所在的栈(此时a在栈顶) for (int i = 0; i < blocks.size(); ++i) { if (!blocks[i].empty() && blocks[i].back() == a) { aStack = i; break; } } // 找到b所在的栈(此时b在栈顶) for (int i = 0; i < blocks.size(); ++i) { if (!blocks[i].empty() && blocks[i].back() == b) { bStack = i; break; } } if (aStack != -1 && bStack != -1) { blocks[aStack].pop_back(); blocks[bStack].push_back(a); } }修正
over函数
确保找到正确的a、b所在栈后再执行移动:void over(int a, int b, vector<vector<int>> &blocks) { returnAllPos(a, blocks); int bStack = -1, aStack = -1; // 找到b所在的栈 for (int i = 0; i < blocks.size(); ++i) { if (find(blocks[i].begin(), blocks[i].end(), b) != blocks[i].end()) { bStack = i; break; } } // 找到a所在的栈 for (int i = 0; i < blocks.size(); ++i) { if (!blocks[i].empty() && blocks[i].back() == a) { aStack = i; break; } } if (aStack != -1 && bStack != -1) { blocks[aStack].pop_back(); blocks[bStack].push_back(a); } }修正
pileover函数
原函数错误地将b作为栈索引,需先找到b所在的栈,再将a及其上方的积木移动到该栈顶部:void pileover(int a, int b, vector<vector<int>> &blocks) { int aStack = -1, aPos = -1; // 找到a所在的栈和位置 for (int i = 0; i < blocks.size(); ++i) { auto it = find(blocks[i].begin(), blocks[i].end(), a); if (it != blocks[i].end()) { aStack = i; aPos = it - blocks[i].begin(); break; } } if (aStack == -1) return; int bStack = -1; // 找到b所在的栈 for (int i = 0; i < blocks.size(); ++i) { if (find(blocks[i].begin(), blocks[i].end(), b) != blocks[i].end()) { bStack = i; break; } } if (bStack == -1) return; // 移动a及其上方的积木到b所在栈 vector<int> temp; for (int i = aPos; i < blocks[aStack].size(); ++i) { temp.push_back(blocks[aStack][i]); } blocks[aStack].erase(blocks[aStack].begin() + aPos, blocks[aStack].end()); for (int elem : temp) { blocks[bStack].push_back(elem); } }pileonto函数无需修改逻辑,只需确保returnAllPos和pileover修正正确即可
内容的提问来源于stack exchange,提问作者Zain
相关产品推荐
相关产品推荐

