UVa 101 - The Blocks Problem

算不算17第一题呢?

题目大意:搭积木。输入一个 int ,代表积木总数,积木按 0 ~ n-1 编号。四个口令表示不同的搭积木操作。

--
move a onto ba,b上的积木放回原来的位置,然后a 及 a 以上的积木移动到 b 上
move a over ba 上的积木放回原来的位置,然后a 及 a 以上的积木移动到 b 上
pile a onto bb 上的积木放回原来的位置,然后a 及 a 以上的积木移动到 b 上
pile**a** over ba 及 a 以上的积木移动到 b 上

然后总结一下

--
movea 上的积木放回
pileb 上的积木放回

无论执行何种操作最后 a 及 a 以上的积木都要移动到 b 上

所以就是写两个函数,一个用于将指定积木上的积木放回,另一个用于移动积木。当然还需要一个查找积木位置的函数。

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;

vector<int>block[26];
int n;

void find( int &p, int &h, int num ){
  for( p = 0; p < n; p++) 
     for( h = 0; h < block[p].size(); h++ )
        if( block[p][h] == num ) return ;
 }

void putback(int p, int h, int num) {
  for(int i = block[p].size() - 1 ; i > h; i--) {
      int a = block[p][i];
      block[a].push_back(a);
  }
  block[p].resize(h+1);
}

void puton(int pa, int ha, int pb, int hb, int a, int b ) {
  block[pb].insert( block[pb].end(), block[pa].begin()+ha, block[pa].end() );
  int size = block[pa].size();
  block[pa].erase(block[pa].begin()+ha, block[pa].end());
}

int main() {
  cin >> n;
  for( int i = 0; i < n; i++ )
     block[i].push_back(i);

  string s1, s2;
  int a, b;
  while( cin >> s1) {
    if( s1 == "quit") break;
    cin >> a >> s2 >> b;
  int pa , ha , pb , hb ;
    find(pa, ha, a);
    find(pb, hb, b);
    if(pa == pb) continue;
    if( s1 == "move") putback(pa, ha, a);
    if( s2 == "onto") putback(pb, hb, b);
    puton(pa, ha, pb, hb, a, b );
  }    
  for( int i = 0; i < n; i++ ) {
     cout << i << ":";
     for( int j = 0; j < block[i].size(); j++)
       cout << " " << block[i][j];
     cout << endl;
  }  
  return 0;
}

PS:一个小细节,一开始是每次需要查找指定编号的木块时就调用一次 find ,然后报错。后来发现每次操作其实在需要 a 和 b 的位置的参数时,它们是不变的,那么只要在最开始查找一次即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值