- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
NOIP2009靶形数独解题报告NOIP2009靶形数独解题报告
靶形数独解题报告
题目来源:NOIP2009 TG 4
题目概述最大。
P.S 这份题解只有50%原创,代码都不是我的……
主要考察知识点
解题思路’的做法。30分做法的话就是有一个弊端,每次检查每行每列以及每个九宫格有没填过k都要进行一次扫描(一般27次),这样本来状态量就大,在这里耗费了一个状态大量时间就有劣势。我们可以用类似状态压缩的思路来解决更新状态的难处。
设有数组hang[1..9] of longint记录9个longint,表示1~9行的填数情况。
假设我现在要在第一行填一个数字8(不用具体到第几行第几列,我们关心的是行而不是一格)。
那么就
hang[1]:=hang[1]+(1 shl (8-1));
相当于在这个数的二进制形式第八位+1。
40分做法实际上是回溯法做的,那么消去这位的方法也和上面类似
hang[1]:=hang[1]-(1 shl (8-1));
实际操作中为了减少代码量用个子过程。
procedure change(i,j,p:longint); //在行i摆数字j
begin
hang[i]:=hang[i]+p*(1 shl (j-1));
end;
举例:行5放8: change(5,8,1)
行5消去8: change(5,8,-1)
这样就实现了O(1)的判断和状态生成。拿到40分。
【45分做法】第二次交,在上面的基础上加个卡时(玩RP啊),我设的是timelimit=2700000
【100分做法,参程做法】至今没懂也没用过。使用M67神的八皇后位运算解题思想。
这回位运算就不限于我那么2的用来检测了……
这个位运算方法还能一次性找出所有能填的数(45分做法里面还有一个for i:= 1 - 9来枚举检查)。注意一下C/C++的位运算 分别为pas的shr, shl。
: and |: or ^: xor
/blog/archives/263
【100分做法,草根做法】第五次交……(直接被PIA),由于数独越里面权值越大,我们可以不按部就班的一个一个搜,而是按照从外圈向内圈(或从内圈向外圈)的顺序进行搜索。这样能保证最早的方案权值尽可能的大。如果有两个格子的选择范围一样大, 那么优先搜索尽量靠里的格子/blog/static/164280893201057102350461/
P.S:其实它很短。见参程2;
好了就这些了…… 至于lqs牛的90分解法也可以问下。
参考程序#includestdio.h#includemath.h int h[10]={},hs[10]={},zs[10]={},xj[5][5]={},hq[10]={};int ans=-1,st[10],a[10][10];void make(){ int sum=0,i,j; fo r (i=1;i5;i++) ?{fo r (j=i;j11-i;j++) sum+=(a[i][j]+a[10-i][j])*(5+i); ? fo r (j=i+1;j10-i;j++) sum+=(a[j][i]+a[j][10-i])*(5+i); } sum+=a[5][5]*10; if (sumans) ans=sum;}void dfs(int k){ if (k==10) make(); else { ?int x,y,j,pos,p,i=st[k]; ?x=511-h[i]; ?y=x-x; ?h[i]|=y; ?j=(int)log2(y)+1; ?pos=511-(hs[i]|zs[j]|xj[(i-1)/3][(j-1)/3]); ?while (pos0) ?{p=pos-pos; ? pos-=p; ? a[i][j]=(int)log2(p)+1; ? hs[i]|=p; ? zs[j]|=p; ? xj[(i-1)/3][(j-1)/3]|=p; ? if (x==y) dfs(k+1); ? else dfs(k); ? hs[i]-=p; ? zs[j]-=p; ? xj[(i-1)/3][(j-1)/3]-=p; ? }; ? h[i]-=y; ? };}int main(){ int i,j,p0; fo r (i=1;i10;i++) ?fo r (j=1;j10;j++) {scanf(%d,a[i][j]); if (a[i][j]0) ? {h[i]|=1(j-1
文档评论(0)