题意:N个Block,有四种操作可以相互移动Block使得他们叠起来。给出操作序列,求最后的状态。
Idea:模拟。
不算难,但是题意、一些细节要注意下。
#include <cstdio>
#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
#define OP(s) cout<<#s<<"="<<s<<" ";
#define PP(s) cout<<#s<<"="<<s<<endl;
using namespace std;
static int s[300][300],h[300],pos[300];
void remove(int pa,int a)
{
int i;
for (i = 1; i <= h[pa]; i++)
if (s[pa][i] == a) break;
for (; i < h[pa]; i++)
s[pa][i] = s[pa][i+1];
h[pa]--;
}
void moveonto(int a,int pb,int b)
{
int i;
for (i = 1; i <= h[pb]; i++)
if (s[pb][i] == b) break;
for (int j = h[pb]; j > i; j--) //j >= i
s[pb][j+1] = s[pb][j];
s[pb][i+1] = a;//s[pb][i] = a;
pos[a] = pb;
h[pb]++;
}
void moveover(int a,int pb)
{
s[pb][++h[pb]] = a;
pos[a] = pb;
}
void pileonto(int pa,int a,int pb,int b)
{
int i;
for (i = 1; i <= h[pa]; i++)
if (s[pa][i] == a) break;
int j;
for (j = 1; j <= h[pb]; j++)
if (s[pb][j] == b) break;
int sum = h[pa] - i + 1;
for (int k = h[pb]; k > j; k--)
s[pb][k+sum] = s[pb][k];
for (int k = j+1; i <= h[pa]; i++,k++)
{
int t = s[pa][i];
s[pb][k] = t;
pos[t] = pb;
}
h[pa] -= sum;
h[pb] += sum;
}
void pileover(int pa,int a,int pb,int b)
{
int i;
for (i = 1; i <= h[pa]; i++)
if (s[pa][i] == a) break;
int sum = h[pa] - i + 1;
for (; i <= h[pa]; i++)
{
int t = s[pa][i];
s[pb][++h[pb]] = t;
pos[t] = pb;
}
h[pa] -= sum;
}
int main()
{
freopen("test.txt","r",stdin);
int N;
scanf("%d",&N);
for (int i = 0; i <= 30; i++)
{
s[i][1] = i;
h[i] = 1;
pos[i] = i;
}
string cmd;
int a,b,pa,pb;
while (cin>>cmd,cmd != "quit")
{
if (cmd == "move")
{
cin>>a>>cmd>>b;
pa = pos[a];
pb = pos[b];
if (pa == pb) continue;
if (cmd == "onto")
{
remove(pa,a);
moveonto(a,pb,b);
}
else
{
remove(pa,a);
moveover(a,pb);
}
}
else
{
cin>>a>>cmd>>b;
pa = pos[a];
pb = pos[b];
if (pa == pb) continue;
if (cmd == "onto")
{
pileonto(pa,a,pb,b);
}
else
{
pileover(pa,a,pb,b);
}
}
}
for (int i = 0; i < N; i++)
{
printf("%d:",i);
for (int j = 1; j <= h[i]; j++) printf(" %d",s[i][j]);
printf("\n");
}
return 0;
}
/*
1/4
开始以为是道简单题,没多想就去写了。
1.开始题意给理解错了,把moveonto,A->B理解成了让a、b上其余的block都移动回最初的位置,题意其实是插入的意思;
2.a->b 开始写成了把a移动到第b堆,事实上b所在的堆 != 第b堆。
3.细节的把握,a-moveonto-b,a 是在b 的后面一个位置,而我写成了在b所在的位置
总之,对于稍复杂的模拟题做的不尽人意,加油~
*/