You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 20:57:04