uva 101 - The Blocks Problem

点击打开链接

题目意思:

在早期人工智慧的領域中常常會用到機器人,在這個問題中有一支機器手臂接受指令來搬動積木,而你的任務就是輸出最後積木的情形。
(編號從0到n-1)0號積木放在0號位置上,1號積木放在1號位置上
機器手臂有以下幾種合法搬積木的方式(a和b是積木的編號)

move a onto b
在將a搬到b上之前,先將a和b上的積木放回原來的位置(例如:1就放回1的最開始位罝) 
move a over b
在將a搬到b所在的那堆積木之上之前,先將a上的積木放回原來的位罝(b所在的那堆積木不動) 
pile a onto b
將a本身和其上的積木一起放到b上,在搬之前b上方的積木放回原位 
pile a over b
將a本身和其上的積木一起搬到到b所在的那堆積木之上 
quit
動作結束 
前四個動作中若a=b,或者a, b在同一堆積木中,那麼這樣的動作算是不合法的。所有不合法的動作應該被忽略,也就是對各積木均無改變。

Input
輸入含有多組測試資料,每組測試資料的第一列有一個正整數n(0 < n < 25),代表積木的數目(編號從0到n-1)。接下來為機器手臂的動作,每個動作一列。如果此動作為 quit ,代表此組測試資料輸入結束。你可以假設所有的動作都符合上述的樣式。請參考Sample Input。

Output
每組測試資料輸出桌面上各位置積木的情形(每個位置一列,也就是共有n列),格式請參考Sample Output。

解题思路: 我们可以用一个vector,在vector里面放list,那么我们就可以实现对单个木块或一堆木块的移动和删除进行操作了,注意list是循环链表对于迭代器的小心使用不然出现指针越界会有内存爆掉的情况,然后就是注意如果a = b 或 a 和 b 在同一堆那么这个命令直接无视,最后就是去模拟这个过程了。

代码:

//如果x == y 或 x和y在同一堆都是不用移动的
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstring>
#include <vector>
#include <cstdio>
#include <stack>
#include <list>
using namespace std;

int n;
string str1, str2;
int x, y;
vector<list<int> >v;

//初始化函数
void init() {
    v.clear();//清空链表
    for (int i = 0; i < n; i++) {
        list<int>l;
        l.push_back(i);
        v.push_back(l);
    }
}

//处理移动
void solve() {
    list<int>::iterator it;
    int cnt, flag;
    int i;
    //先找到x和y的位置,在同一堆就return
    for (i = 0; i < n; i++) {//查找x
        it = find(v[i].begin(), v[i].end(), x); //返回找到的位置   
        if (it != v[i].end()) {//如果不是末尾说明找到了
            cnt = i;
            break; //跳出这个查找
        }
    }
    for (i = 0; i < n; i++) {//查找y
        it = find(v[i].begin(), v[i].end(), y); //返回找到的位置   
        if (it != v[i].end()) {//如果不是末尾说明找到了
            flag = i;
            break; //跳出这个查找
        }
    }
    if (cnt == flag)//如果在相同的位置那么就return;
        return;
    //如果是单个移动
    else if (str1 == "move") {//如果第一个单词是move  
        it = v[cnt].end();//先把x上面的元素移动到原来位置
        it--;
        for (; *it != x; it--) {
            v[*it].push_back(*it); //移动
            v[cnt].erase(it); //删除
        }
        v[cnt].erase(it);//删除x
        if (str2 == "onto") {//第二个单词是onto
            it = v[flag].end();
            it--;
            for (; *it != y; it--){
                 v[*it].push_back(*it);//把y上面的元素插入到原先的位置
                 v[flag].erase(it);//删除该元素
            }
            v[flag].push_back(x);//最后把x插入即可
        }
        else //如果第二个是over
             v[flag].push_back(x); //直接插入到list最后位置即可 
    }
    //如果移动的是一整个
    else {
          if (str2 == "onto") {//第二个是onto就要处理一下y上面的元素
             it = v[flag].end();
             it--;
             for (; *it != y; it--) {
                  v[*it].push_back(*it);
                  v[flag].erase(it);
             }
          }
          it = v[cnt].begin();
          for (; it != v[cnt].end(); it++) {
              if (*it == x) {
                 for (; it != v[cnt].end(); it++)
                     v[flag].push_back(*it);
                 break;
              }
          }
          it = v[cnt].end();
          it--;
          for (; *it != x; it--)
              v[cnt].erase(it);
          v[cnt].erase(it);
    }
}

//输出函数
void output() {
    list<int>::iterator it;
    for (int i = 0; i < n; i++) {
        printf("%d:", i); //输出是第几个
        for (it = v[i].begin(); it != v[i].end(); it++)//利用迭代器来输出
            printf(" %d", *it);
        printf("\n");
    }
}

//主函数
int main() {
    scanf("%d", &n);
    init();
    while (cin >> str1 && str1 != "quit") {
        cin >> x >> str2 >> y;
        if (x != y)
            solve();
    }
    output();
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值