NOIP 2011向上グループMayan


タイトルサイト
【問題解きの考え方】
時間が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; }