zoukankan      html  css  js  c++  java
  • [BZOJ1501][NOI2005]智慧珠游戏

    bzoj
    luogu

    sol

    pj难度,打表打到死。

    int b[12]={4,2,8,1,4,8,4,8,8,1,4,8};
    int c[12]={3,4,4,4,5,5,5,5,5,5,5,5};
    

    以上(b,c)数组分别表示每个块的旋转方式以及块的大小。这就是打表的总量。
    直接按位置dfs即可。
    我一开始还按块的编号dfs结果T到飞我真的太naive了

    code

    打表,比yyb的11k代码短多了(虽然跑得比他的要慢)

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    char ch[20];
    int vis[20][20],to[20][20],used[20];
    
    int a[12][8][5][2]={
    	{
    		{ {0,0},{0,1},{1,0} },
    		{ {0,0},{0,1},{1,1} },
    		{ {0,0},{1,0},{1,1} },
    		{ {0,0},{1,-1},{1,0} }
    	},//A
    	{
    		{ {0,0},{0,1},{0,2},{0,3} },
    		{ {0,0},{1,0},{2,0},{3,0} }
    	},//B
    	{
    		{ {0,0},{0,1},{0,2},{1,0} },
    		{ {0,0},{0,1},{0,2},{1,2} },
    		{ {0,0},{1,0},{1,1},{1,2} },
    		{ {0,0},{1,-2},{1,-1},{1,0} },
    		{ {0,0},{0,1},{1,1},{2,1} },
    		{ {0,0},{0,1},{1,0},{2,0} },
    		{ {0,0},{1,0},{2,-1},{2,0} },
    		{ {0,0},{1,0},{2,0},{2,1} }
    	},//C
    	{
    		{ {0,0},{0,1},{1,0},{1,1} }
    	},//D
    	{
    		{ {0,0},{0,1},{0,2},{1,2},{2,2} },
    		{ {0,0},{0,1},{0,2},{1,0},{2,0} },
    		{ {0,0},{1,0},{2,0},{2,1},{2,2} },
    		{ {0,0},{1,0},{2,0},{2,-1},{2,-2} }
    	},//E
    	{
    		{ {0,0},{0,1},{0,2},{0,3},{1,1} },
    		{ {0,0},{0,1},{0,2},{0,3},{1,2} },
    		{ {0,0},{1,-1},{1,0},{1,1},{1,2} },
    		{ {0,0},{1,-2},{1,-1},{1,0},{1,1} },
    		{ {0,0},{1,0},{2,0},{3,0},{1,-1} },
    		{ {0,0},{1,0},{2,0},{3,0},{2,-1} },
    		{ {0,0},{1,0},{2,0},{3,0},{1,1} },
    		{ {0,0},{1,0},{2,0},{3,0},{2,1} }
    	},//F
    	{
    		{ {0,0},{0,1},{0,2},{1,0},{1,2} },
    		{ {0,0},{0,2},{1,0},{1,1},{1,2} },
    		{ {0,0},{0,1},{1,0},{2,0},{2,1} },
    		{ {0,0},{0,1},{1,1},{2,0},{2,1} }
    	},//G
    	{
    		{ {0,0},{0,1},{1,0},{1,1},{0,2} },
    		{ {0,0},{0,1},{1,0},{1,1},{1,2} },
    		{ {0,0},{0,1},{1,0},{1,1},{2,1} },
    		{ {0,0},{0,1},{1,0},{1,1},{2,0} },
    		{ {0,0},{1,0},{1,1},{2,0},{2,1} },
    		{ {0,0},{1,-1},{1,0},{2,-1},{2,0} },
    		{ {0,0},{0,1},{0,2},{1,1},{1,2} },
    		{ {0,0},{0,1},{1,-1},{1,0},{1,1} }
    	},//H
    	{
    		{ {0,0},{0,1},{1,-2},{1,-1},{1,0} },
    		{ {0,0},{0,1},{1,1},{1,2},{1,3} },
    		{ {0,0},{0,1},{0,2},{1,2},{1,3} },
    		{ {0,0},{0,1},{0,2},{1,-1},{1,0} },
    		{ {0,0},{1,0},{2,-1},{2,0},{3,-1} },
    		{ {0,0},{1,0},{2,0},{2,1},{3,1} },
    		{ {0,0},{1,0},{1,1},{2,1},{3,1} },
    		{ {0,0},{1,-1},{1,0},{2,-1},{3,-1} }
    	},//I
    	{
    		{ {0,0},{1,-1},{1,0},{1,1},{2,0} }
    	},//J
    	{
    		{ {0,0},{0,1},{1,1},{1,2},{2,2} },
    		{ {0,0},{1,0},{1,1},{2,1},{2,2} },
    		{ {0,0},{0,1},{1,-1},{1,0},{2,-1} },
    		{ {0,0},{1,-1},{1,0},{2,-2},{2,-1} }
    	},//K
    	{
    		{ {0,0},{0,1},{0,2},{0,3},{1,0} },
    		{ {0,0},{0,1},{0,2},{0,3},{1,3} },
    		{ {0,0},{1,0},{1,1},{1,2},{1,3} },
    		{ {0,0},{1,-3},{1,-2},{1,-1},{1,0} },
    		{ {0,0},{1,0},{2,0},{3,0},{0,1} },
    		{ {0,0},{1,0},{2,0},{3,0},{3,1} },
    		{ {0,0},{1,0},{2,0},{3,0},{0,-1} },
    		{ {0,0},{1,0},{2,0},{3,0},{3,-1} },
    	}//L
    };
    int b[12]={4,2,8,1,4,8,4,8,8,1,4,8};
    int c[12]={3,4,4,4,5,5,5,5,5,5,5,5};
    
    bool check(int t,int p,int q,int k)
    {
    	for (int i=0;i<c[t];++i)
    	{
    		int x=p+a[t][k][i][0],y=q+a[t][k][i][1];
    		if (x<1||x>10||y<1||y>x) return false;
    		if (vis[x][y]!=-1) return false;
    	}
    	return true;
    }
    
    void cover(int t,int p,int q,int k,int val)
    {
    	for (int i=0;i<c[t];++i)
    		vis[p+a[t][k][i][0]][q+a[t][k][i][1]]=val;
    }
    
    void print()
    {
    	for (int i=1;i<=10;++i,puts(""))
    		for (int j=1;j<=i;++j)
    			printf("%c",vis[i][j]+'A');
    	exit(0);
    }
    
    int tot;
    void go(int x,int y)
    {
    	if (x<1||x>10||y<1||y>x) return;
    	if (vis[x][y]!=-1||to[x][y]==1) return;
    	++tot;to[x][y]=1;
    	go(x+1,y);go(x-1,y);go(x,y+1);go(x,y-1);
    }
    
    bool judge()
    {
    	memset(to,0,sizeof(to));
    	for (int i=1;i<=10;++i)
    		for (int j=1;j<=i;++j)
    			if (vis[i][j]==-1&&to[i][j]==0)
    			{
    				tot=0;go(i,j);
    				if (tot<3) return false;
    			}
    	return true;
    }
    
    void dfs(int x,int y)
    {
    	if (x==11) print();
    	if (y>x) dfs(x+1,1);
    	if (vis[x][y]!=-1) {dfs(x,y+1);return;}
    	for (int i=0;i<12;++i)
    		if (!used[i])
    			for (int j=0;j<b[i];++j)
    				if (check(i,x,y,j))
    				{
    					cover(i,x,y,j,i);used[i]=1;
    					dfs(x,y+1);
    					cover(i,x,y,j,-1);used[i]=0;
    				}
    }
    
    int main()
    {
    	memset(vis,-1,sizeof(vis));
    	for (int i=1;i<=10;++i)
    	{
    		scanf("%s",ch+1);
    		for (int j=1;j<=i;++j)
    			if (ch[j]!='.') vis[i][j]=ch[j]-'A',used[ch[j]-'A']=1;
    	}
    	if(judge())dfs(1,1);
    	puts("No solution");
    	return 0;
    }
    
  • 相关阅读:
    .IllegalArgumentException: Mapped Statements collection does not contain 异常一例【我】
    Spring配置文件里加载路径中的通配符
    线程池使用Callable示例【我】
    使用Callable和Future接口创建线程
    Java线程池(Callable+Future模式)
    集合切割
    draw call 理解和优化
    Unity 3d导入3dMax模型 产生若干问题
    3dmax做的模型导入U3d后 当模型靠近摄像机时镂空问题
    不管多少个空格替换为一个空格
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8480734.html
Copyright © 2011-2022 走看看