1. 程式人生 > >洛谷P2790 ccj與zrz之積木問題 題解

洛谷P2790 ccj與zrz之積木問題 題解

題目連結:https://www.luogu.org/problemnew/show/P2790

這題碼量稍有點大。。。

分析:

這道題模擬即可。因為考慮到所有的操作vector可最快捷的實現,所以陣列動態vector。每一種情況分別考慮。

其他的見程式碼註釋

部分過長的註釋防在這裡,請對照序號到程式碼中檢視。

:wa意為a的位置,記錄當前a所在位置的序號。
wb意為b的位置,記錄當前b所在位置的序號。
ca意為a的層數,記錄當前a所在這堆積木中第幾個。
cb意為b的層數,記錄當前b所在這堆積木中第幾個。

其他定義顯而易見。

:search遍歷一遍所有位置所有積木,找到a或b後記錄他們的位置和位置中第幾個,相當於為後面的一個初始化吧。

:此函式即move onto,按照題意模擬即可,之後④⑤⑥均如此,具體模擬步驟會詳細說明。

程式碼:

#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
int wa,wb,ca,cb;//①
char s1[10],s2[10];
int a,b;
vector<int>v[30];
int n;
void search()//②
{
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<v[i].size();j++
) { if(v[i][j]==a) { wa=i; ca=j; } if(v[i][j]==b) { wb=i; cb=j; } } } } void moon()//③ { for(int i=ca+1;i<v[wa].size();i++) { v[v[wa][i]].push_back(v[wa][i]); }//把a以上的歸位 for(int i=cb+1;i<v[wb].size();i++) { v[v[wb][i]].push_back(v[wb][i]); }//把b以上的歸位 v[
wa].resize(ca);//只保留當前vector到a-1 v[wb].resize(cb+1);//但是b要保留,因為a是要摞到b上的 v[wb].push_back(a);//摞上去 }//下面的都換湯不換藥,我想大家都應該知道 void moov()//④ { for(int i=ca+1;i<v[wa].size();i++) { v[v[wa][i]].push_back(v[wa][i]); } v[wa].resize(ca); v[wb].push_back(a); } void pion()//⑤ { for(int i=cb+1;i<v[wb].size();i++) { v[v[wb][i]].push_back(v[wb][i]); } v[wb].resize(cb+1); for(int i=ca;i<v[wa].size();i++) { v[wb].push_back(v[wa][i]); } v[wa].resize(ca); } void piov()//⑥ { for(int i=ca;i<v[wa].size();i++) { v[wb].push_back(v[wa][i]); } v[wa].resize(ca); } int main() { scanf("%d",&n); for(int i=0;i<n;i++) { v[i].push_back(i); } while(1) { scanf("%s",s1); if(strcmp(s1,"quit")==0)break;//提前判斷是否退出 scanf("%d%s%d",&a,s2,&b); search(); if(wa==wb)continue;//根據題意,如果a和b在同一堆,那麼忽略 if(strcmp(s1,"move")==0&&strcmp(s2,"onto")==0)moon(); if(strcmp(s1,"move")==0&&strcmp(s2,"over")==0)moov(); if(strcmp(s1,"pile")==0&&strcmp(s2,"onto")==0)pion(); if(strcmp(s1,"pile")==0&&strcmp(s2,"over")==0)piov(); //逐一判斷每種操作,其中相應的子函式對應去兩個單詞的首字母連起來 } for(int i=0;i<n;i++) { printf("%d:",i);//暫時不輸出括號,有了再打 for(int j=0;j<v[i].size();j++) { printf(" %d",v[i][j]);//當前位置有積木,那麼就打出來,別忘了空格 } printf("\n");//每次換行 } return 0; }