題意:有四行n列的車場,k輛車,一開始這些車都在第二行和第三行,第一行和第四行是停車的地方,標號代表對應的車只能停到該停車位,第一行和第四行0代表不能停車,第二行和第三行0代表有空位,問是否能通過不超過20000次的移動使得所有車進入停車位。(停車位是滿足的)
分析:借鑑大神的思路,只要一開始第二行和第三行有空位或者能夠有車進入停車位,則會滿足第二行和第三行有空位,則以空位爲頭,按照一個方向旋轉,就能保證每個車到達對應的車位,移動次數不超過100×100+100,滿足條件。按照題意模擬即可。這裏將第一行和第四行合併成一組,第二行和第三行合併成一組,注意順序即可。
代碼:
#include<bits/stdc++.h>
using namespace std;
int a[110][110];
int n,k,s;
struct node{
int id,x,y;
node(int id,int x,int y):id(id),x(x),y(y){};
};
vector<node>ans;
void stop()//停車
{
for(int i = 0; i < 2 * n; i++)//有車且對應標號相同
{
if(a[1][i] && (a[1][i] == a[0][i]))
{
ans.push_back((node){a[1][i], i / n == 1? 4:1, i % n + 1});
a[1][i] = 0;//車道該位置爲空
k--;//入停車位
}
}
}
bool judge()//開始判斷通道是否有空位或者停車之後是否有空位
{
stop();
for(int i = 0; i < 2 * n; i++)
{
if(!a[1][i])return true;
}
return false;
}
void turn()
{
vector<node>v1,v2;//v從後往前,v2存放車頭及其之後的車輛,v1存放車頭之前的車輛,車頭是空位,先動,v1接在v2的後面
int t = a[1][2 * n - 1];
for(int i = 2 * n - 1; i >= 1; i--)
{
a[1][i] = a[1][i - 1];
if(a[1][i])
{
if(i > s)
v1.push_back((node){a[1][i], i / n == 1 ? 3:2,i % n + 1});
else
v2.push_back((node){a[1][i],i / n == 1 ? 3:2, i % n + 1});
}
}
a[1][0] = t;
if(t)v2.push_back((node){t,2,1});
vector<node>::iterator it;
for(it = v2.begin(); it != v2.end(); it++)
{
ans.push_back(*it);
}
for(it = v1.begin(); it != v1.end(); it++)
{
ans.push_back(*it);
}
}
int main()
{
cin>>n>>k;
for(int i = 0; i < n; i++)cin>>a[0][i];
for(int i = 0; i < n; i++)cin>>a[1][i];
for(int i = 2 * n - 1; i >= n; i--)cin>>a[1][i];//注意正着輸入倒着存放
for(int i = 2 * n - 1; i >= n; i--)cin>>a[0][i];
if(!judge()){printf("-1\n");return 0;}
for(int i = 0; i < 2 * n; i++)
{
if(!a[1][i])
{
s = i;
break;
}
}
while(k)
{
stop();
turn();
s = (s + 1) % (2 * n);
}
cout<<ans.size()<<endl;
vector<node>::iterator it;
for(it = ans.begin(); it != ans.end(); it++)
{
int x = (*it).x;
int y = (*it).y;
int id = (*it).id;
if( x == 3 || x == 4)//因爲是倒着存放後兩行,還得變成正着放的
{
y = n - y + 1;
}
printf("%d %d %d\n",id,x,y);
}
return 0;
}