洛谷P2790 ccj與zrz之積木問題 題解
阿新 • • 發佈:2018-12-10
題目連結: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;
}