题目:
首先题意要看懂,“归位”也就是0号木块放回第0堆,1号放回第1堆...
注意到,“move” a 相当于比"pile" a 多一步清空a上部的操作(然后a上方这一摞也就只有a一个了),“onto” b 比"over" b 也多一步清空,那样就可以简化为看是否需要提前清空a, b 上方,再整体挪a到b上方即可Orz_Orz。
关于用什么方法,看到有人手写链表(窝望而生畏%%%),也看到递归的写法(窝个fw木有看懂QAQ)->(好了看懂了窝又来了,附在后面).还是动态数组(vector)好理解(对于窝而言)
【plus:不定长数组vector,可用clear()清空,resize()改变大小,用push_back()和pop_back()在尾部添加和删除元素,用empty()测试是否为空。vector之间可以直接赋值或者作为函数的返回值,像是“一等公民”一样。】
AC代码:
#include#include #include using namespace std; int n; vector pile[30]; //找木块a所在的pile和height,用引用的方式返回调用者 void find_block(int x, int& p, int& h){ for(p=0; p >n; int a, b; string s1,s2; for(int i=0;i >s1>>a>>s2>>b){ int pa,pb,ha,hb; find_block(a,pa,ha); find_block(b,pb,hb); if(pa==pb)continue; if(s1=="move")clear_above(pa,ha); if(s2=="onto")clear_above(pb,hb); pile_onto(pa,ha,pb); } print(); return 0; }
#includeint n; struct blocks{ int up,down; }block[25]; int find_up(int x){ if(block[x].up==-1)return x; return find_up(block[x].up); } int find_down(int x){ if(block[x].down==-1)return x; return find_down(block[x].down); } void move_up(int x){ //把x及其上方的归位 if(x==-1)return; block[block[x].down].up=-1;//对木块x下方的木块的影响(它上面空了) block[x].down=-1; //x木块本身回到原位,它的下方改为-1 move_up(block[x].up); } void solve(int x){ printf(" %d",x); if(block[x].up==-1) return; else solve(block[x].up); } int main(){ int i; scanf("%d",&n); for(i=0;i 一开始主要是move_up()函数的block[block[x].down].up=-1;没看懂,心想"x下面的上面不就是它自己吗?" “那为什么不直接写x=-1”呢?后来突然想起它的对象是block,对于x下方的木块的影响要体现在x下方的木块上。然后依次递归,其实画个图也好理解。
然后lsgg说有一道很相似的国家级的邀请赛的题,当时是过了就能“稳铜牌”:
Stacks - HDU 6947 - Virtual Judge
(不过由于“护网行动”网站关闭暂不能提交,听说是要6.1号后开放)



