DLX写炸了,样例就超时,求大佬看看
查看原帖
DLX写炸了,样例就超时,求大佬看看
405894
233L楼主2022/5/4 09:31

写起来还算快,调了快2小时,还是不知道错哪ww

目前知道的是dfs的过程中有一步走偏了,代码里面有一行注释掉的if,下一个row就走偏了

#include<bits/stdc++.h>
#define N 17
#define R 4097
#define C 1025
#define L 17409//L=R*4+C
using namespace std;
int t1=clock();
int a[N][N];
inline void id_fill(int id){
	id--;
	a[(id>>8)+1][((id>>4)&15)+1]=(id&15)+1;
}
struct DLX{
	int cnt;
	int head[R],stk[256];
	int row[L],col[L],siz[C];
	int u[L],d[L],l[L],r[L];
	
	inline void init(){
		cnt=1024;
		memset(head,0,sizeof(head));
		for(int i=0;i<=cnt;i++){
			u[i]=d[i]=i;
			l[i]=i-1,r[i]=i+1;
			siz[i]=0;
		}
		l[0]=cnt,r[cnt]=0;
	}
	inline void insert(int x,int y){
		cnt++,siz[y]++;
		row[cnt]=x,col[cnt]=y;
		u[cnt]=y,d[cnt]=d[y];
		u[d[y]]=cnt,d[y]=cnt;
		if(!head[x]){
			head[x]=l[cnt]=r[cnt]=cnt;
			return;
		}
		l[cnt]=l[head[x]],r[cnt]=head[x];
		l[head[x]]=r[l[head[x]]]=cnt;
	}
	inline void remove(int y){
		l[r[y]]=l[y],r[l[y]]=r[y];
		for(int i=d[y];i!=y;i=d[i]){
			for(int j=r[i];j!=i;j=r[j]){
				u[d[j]]=u[j],d[u[j]]=d[j];
				siz[col[j]]--;
			}
		}
	}
	inline void recover(int y){
		l[r[y]]=r[l[y]]=y;
		for(int i=d[y];i!=y;i=d[i])
			for(int j=r[i];j!=i;j=r[j]){
				u[d[j]]=d[u[j]]=j;
				siz[col[j]]++;
			}
	}
	bool dance(int dep){
		if(!r[0]){
			for(int i=0;i<dep;i++)id_fill(stk[i]);
			return 1;
		}
		int id=r[0];
		for(int i=r[0];i;i=r[i])
			if(siz[i]<siz[id])id=i;
		remove(id);
		for(int i=d[id];i!=id;i=d[i]){
			stk[dep]=row[i];
//			if(row[i]==539)
			for(int j=r[i];j!=i;j=r[j])remove(col[j]);
			if(dance(dep+1))return 1;
			for(int j=r[i];j!=i;j=r[j])recover(col[j]);
		}
		recover(id);
		return 0;
	}
}dlx;

inline bool jch(char ch){//judge_ch
	return ch=='-'||(ch>='A'&&ch<='Z');
}
inline int getn(){
	char ch=getchar();
	while(!jch(ch))ch=getchar();
	return ch=='-'?0:ch^64;
}
inline int get_row(int x,int y,int val){
	//x [1,16]
	//y [1,16]
	//val [1,16]
	return (((x-1)<<8)|((y-1)<<4)|(val-1))+1;
}
inline int get_col(int x,int y,int z){
	//x [1,4]
	//y [1,16]
	//z [1,16]
	return (((x-1)<<8)|((y-1)<<4)|(z-1))+1;
}
inline int getg(int x,int y){
	return ((x-1)>>2<<2)+((y+3)>>2);
}
inline void add(int x,int y,int val){
	int line=get_row(x,y,val);
	dlx.insert(line,get_col(1,x,val));
	dlx.insert(line,get_col(2,y,val));
	dlx.insert(line,get_col(3,getg(x,y),val));
	dlx.insert(line,get_col(4,x,y));
}
inline void init(){
	for(int i=1;i<=16;i++)
		for(int j=1;j<=16;j++){
			a[i][j]=getn();
			for(int k=1;k<=16;k++){
				if(a[i][j]&&a[i][j]!=k)continue;
				add(i,j,k);
			}
		}
}
inline void print(){
	for(int i=1;i<=16;i++){
		for(int j=1;j<=16;j++)
			putchar(a[i][j]^64);
		putchar('\n');
	}
	putchar('\n');
}
int main(){
//	freopen("1.out","w",stdout);
	int t;
	scanf("%d",&t);
	while(t--){
		dlx.init();
		init();
		dlx.dance(0);
		print();
//		printf("cnt=%d\n",dlx.cnt);
	}
}
2022/5/4 09:31
加载中...