题解
二维vector的应用典型例题 , 非常巧妙地是用引用来传递数值 , 非常巧妙 !
再者就是输入指令共同点的提取 , 大大优化了代码的简洁度 , 非常巧妙 !
代码
#include<bits/stdc++.h>
using namespace std ;
#define rg register
const int MAXN = 25+5 ;
vector<int> v[MAXN];
// int n , a , b ;
// string s1 , s2 ;
int n ;
void FIND ( int wd , int &p , int &h ) { // 以引用的形式传递传递参数 h , 非常精妙
for ( p = 0 ; p < n ; ++p )
for ( h = 0 ; h < v[p].size() ; ++h )
if ( v[p][h] == wd ) return ;
}
void CLE ( int p , int h ) { // 清除归位 p 木块上部的所有
for ( rg int i = h+1 ; i < v[p].size() ; ++i ) {
int cur = v[p][i] ;
v[cur].push_back( cur ) ;
}
v[p].resize( h+1 ) ; // 保留 0 - h+1
}
void TO ( int p1 , int h , int p2 ) { // 将 p1堆 h 及以上所有木块 移动到 p2 堆上
for ( rg int i = h ; i < v[p1].size() ; ++i ) {
v[p2].push_back( v[p1][i] ) ;
}
v[p1].resize( h ) ; // 保留 0 - h
}
int main ( ) { ios:: sync_with_stdio( false ) , cin.tie(0) , cout.tie(0) ;
// freopen( "F:\\in\\vector.txt" , "r" , stdin ) ;
int a , b ;
string s1 , s2 ;
cin >> n ;
for ( rg int i = 0 ; i < n ; ++i ) v[i].push_back( i ) ;
while ( cin >> s1 ) {
if ( s1 == "quit" ) break ;
cin >> a >> s2 >> b ;
int pa , pb , ha , hb ;
FIND( a , pa , ha ) ;
FIND( b , pb , hb ) ;
if ( pa==pb ) continue ; // 去掉非法情况 , 但此处很容易想不到 , 特殊数据会导致 wa
if ( s1 == "move" ) CLE( pa , ha ) ;
if ( s2 == "onto" ) CLE( pb , hb ) ;
TO( pa , ha , pb ) ;
}
for ( rg int i = 0 ; i < n ; ++i ) {
cout << i << ":" ;
for ( rg int j = 0 ; j < v[i].size() ; ++j ) {
cout << " " << v[i][j] ;
}
cout << endl ;
}
return 0 ;
}
题目
样例输入
10
move 9 onto 1
move 8 over 1
move 7 over 1
move 6 over 1
pile 8 over 6
pile 8 over 5
move 2 over 1
move 4 over 9
quit
样例输出
0: 0
1: 1 9 2 4
2:
3: 3
4:
5: 5 8 7 6
6:
7:
8:
9: