已过,但是时间
查看原帖
已过,但是时间
1216590
BrokenVessle楼主2024/8/16 10:56

运行时间是其它人DLX的将近十倍(SP的经验也是这样)

#include<iostream>
#include<cstring> 
using namespace std;
struct Node{int left,right,up,down,row,col;}node[1000006];//结点 
struct ST{int id1,id2,id3,id4;};//决策(c,r,w)对应的列号 
struct MP{int r,c,w;}mp[5005];//列号对应的决策 
ST gt(int r,int c,int w)//转化 
{
	return {(r-1)*16+w,256+(c-1)*16+w,512+((r-1)/4*4+(c-1)/4)*16+w,768+(r-1)*16+c};
}
const int m=1024;
int cnt;
int row[5000];//每一行第一个元素 
int lcnt[2000];//列元素个数 
int rcnt;
void build()//初始化 
{
	for(int i=0;i<=m;++i)
		node[i]={i-1,i+1,i,i,0,i};
	node[0].left=m;
	node[m].right=0;
	cnt=m;
}
void finsert(int r,int c)//在DL的(r,c)插入结点 
{
	int p=++cnt;
	node[p].row=r,node[p].col=c;
	node[p].up=node[c].up;
	node[p].down=c;
	node[node[p].up].down=node[node[p].down].up=p;
	++lcnt[c];
	if(!row[r])
	{
		node[p].left=node[p].right=p;
		row[r]=p;
	}
	else
	{
		node[p].left=node[row[r]].left;
		node[p].right=row[r];
		node[node[p].left].right=node[node[p].right].left=p;
	}
}
void fpush(int r,int c,int w)//插入关于决策(r,c,w)的结点 
{
	ST s=gt(r,c,w);
	++rcnt;
	mp[rcnt]={r,c,w};
	finsert(rcnt,s.id1);
	finsert(rcnt,s.id2);
	finsert(rcnt,s.id3);
	finsert(rcnt,s.id4);
}
void fdel(int c)//删除c列 
{
	for(int i=node[c].down;i!=c;i=node[i].down)
		for(int j=node[i].right;j!=i;j=node[j].right)
		{
			node[node[j].up].down=node[j].down;
			node[node[j].down].up=node[j].up;
			--lcnt[node[j].col];
		}
	node[node[c].left].right=node[c].right;
	node[node[c].right].left=node[c].left;
}
void frec(int c)//恢复c列 
{
	node[node[c].left].right=node[node[c].right].left=c;
	for(int i=node[c].up;i!=c;i=node[i].up)
		for(int j=node[i].left;j!=i;j=node[j].left)
		{
			node[node[j].up].down=node[node[j].down].up=j;
			++lcnt[node[j].col];
		}
}
int ans[5005];
char arr[20][20];
int mxstep;
bool dance(int step)//工作 
{
	if(!node[0].right)
	{
		for(int i=1;i<step;++i)
			arr[mp[ans[i]].r][mp[ans[i]].c]=mp[ans[i]].w+'A'-1;
		return true;
	}
	int c=node[0].right;
	for(int i=node[0].right;i;i=node[i].right)
		if(lcnt[i]<lcnt[c])
			c=i;
	fdel(c);
	for(int i=node[c].down;i!=c;i=node[i].down)
	{
		ans[step]=node[i].row;
		for(int j=node[i].right;j!=i;j=node[j].right)
			fdel(node[j].col);
		if(dance(step+1))return true;
		for(int j=node[i].left;j!=i;j=node[j].left)
			frec(node[j].col);
	}
	frec(c);
	return false;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0); 
//	int k;
//	cin>>k;
	int fir=true;
	while(cin>>(arr[1]+1))
	{
		if(fir)fir=false;
		else cout<<'\n';
		cnt=rcnt=0;
		memset(row,0,sizeof row);
		memset(lcnt,0,sizeof lcnt);
		build();
		for(int i=2;i<=16;++i)
			cin>>(arr[i]+1);
		for(int i=1;i<=16;++i)
			for(int j=1;j<=16;++j)
			{
				if(arr[i][j]!='-')
					fpush(i,j,arr[i][j]-'A'+1);//如果有字母了,那么只能有这一个决策 
				else
					for(int k=1;k<=16;++k) 
						fpush(i,j,k);
			}
		dance(1);
		for(int i=1;i<=16;++i)
			cout<<(arr[i]+1)<<'\n';
	}
}
2024/8/16 10:56
加载中...