NOIP 2011向上グループMayan
タイトルサイト
【問題解きの考え方】
時間が3秒なので、検索を考えます.状態数が多く、明らかにBFSで爆発するのでDFSが使えます.枝を切るいくつかの場所:
1.1つのグリッドが左に移動するのは、左のグリッドが右に移動するのと同じです.そのため、各グリッドを列挙して右に移動すればいいです.
2.回転する2つの格子が同じであれば、調整しません.
3.現在の状態のある色の数が3未満で0でない場合、この色が除去されないことは明らかであるため、終了します.
(作成されたコード90、最後のポイントタイムアウトは、RNQOJで測定されました.私はインターネットで多くのコードを探して、RNQOJの上に置いて、まだACができません)
【コード】(タイムアウトの原因を探してほしい)
【問題解きの考え方】
時間が3秒なので、検索を考えます.状態数が多く、明らかにBFSで爆発するのでDFSが使えます.枝を切るいくつかの場所:
1.1つのグリッドが左に移動するのは、左のグリッドが右に移動するのと同じです.そのため、各グリッドを列挙して右に移動すればいいです.
2.回転する2つの格子が同じであれば、調整しません.
3.現在の状態のある色の数が3未満で0でない場合、この色が除去されないことは明らかであるため、終了します.
(作成されたコード90、最後のポイントタイムアウトは、RNQOJで測定されました.私はインターネットで多くのコードを探して、RNQOJの上に置いて、まだACができません)
【コード】(タイムアウトの原因を探してほしい)
#include
#include
#include
#include
#include
using namespace std;
int n;
struct node{
int x,y,p;
}s[10];
inline bool checkclear(int m[5][10])
{
for (int i=0;i<5;i++)
if (m[i][0]!=0) return 0;
return 1;
}
inline void print()
{
for (int i=0;i=0)&&(tmp[i][p]==0))
{
swap(tmp[i][p+1],tmp[i][p]);
p--;
}
}
}
bool checkcolor(int m[5][10])
{
bool fl=1;
int sum[15]={0};
for (int i=0;i<5;i++)
for (int j=0;j<7;j++)
sum[m[i][j]]++;
for (int i=1;i<15;i++)
if ((sum[i]==1)||(sum[i]==2)) return 0;
return 1;
}
void dfs(int step,int m[5][10],int p,int q)
{
if (step==n)
{
if (checkclear(m))
{
print();
exit(0);
}
return;
}
if (!checkcolor(m)) return;
for (int i=0;i<4;i++)
{
for (int j=0;j<7;j++)
{
int tmp[5][10]={0};
memcpy(tmp,m,sizeof(tmp));
if (tmp[i][j]==tmp[i+1][j]) continue;
if (tmp[i][j]!=0)
{
s[step].x=i;
s[step].y=j;
s[step].p=1;
}else
{
s[step].x=i+1;
s[step].y=j;
s[step].p=-1;
}
swap(tmp[i][j],tmp[i+1][j]);
drop(tmp);
bool tf=0;
while (clearm(tmp))
{
drop(tmp);
tf=1;
}
if ((tf==0)&&(p==i)&&(q==j)) continue;
dfs(step+1,tmp,i,j);
}
}
}
int main()
{
scanf("%d",&n);
int m[5][10]={0};
for (int i=0;i<=4;i++)
{
int c=0,tmp;
while ((scanf("%d",&tmp)!=EOF)&&(tmp!=0))
m[i][c++]=tmp;
}
dfs(0,m,-1,-1);
printf("-1
");
return 0;
}