usaco 1.5.4——checker
Checker Challenge 跳棋的挑战
描述
检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列只有一个,每条对角线(包括两条主对角线的所有对角线)上至多有一个棋子。
图见usaco原图
上面的布局可以用序列2 4 6 1 3 5来描述,第i个数字表示在第i行的相应位置有一个棋子,如下:
行号 1 2 3 4 5 6 列号 2 4 6 1 3 5
这只是跳棋放置的一个解。请编一个程序找出所有跳棋放置的解。并把它们以上面的序列方法输出。解按字典顺序排列。请输出前3个解。最后一行是解的总个数。
特别注意: 对于更大的N(棋盘大小N x N)你的程序应当改进得更有效。不要事先计算出所有解然后只输出,这是作弊。如果你坚持作弊,那么你登陆USACO Training的帐号将被无警告删除
格式
PROGRAM NAME: checker
INPUT FORMAT:
(checker.in)
一个数字N (6 <= N <= 13) 表示棋盘是N x N大小的。
OUTPUT FORMAT:
(checker.out)
前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。
SAMPLE INPUT
6
SAMPLE OUTPUT
2 4 6 1 3 5 3 6 2 5 1 4 4 1 5 2 6 3 4
Compiling...
Compile: OK
Executing...
Test 1: TEST OK [0.000 secs, 276 KB]
Test 2: TEST OK [0.000 secs, 276 KB]
Test 3: TEST OK [0.000 secs, 276 KB]
Test 4: TEST OK [0.000 secs, 276 KB]
Test 5: TEST OK [0.000 secs, 276 KB]
Test 6: TEST OK [0.000 secs, 276 KB]
Test 7: TEST OK [0.054 secs, 276 KB]
Test 8: TEST OK [0.162 secs, 276 KB]
All tests OK.
Your program ('checker') produced all correct answers! This is your submission #4 for this problem. Congratulations!
分析:
额。比较经典的N皇后问题
让我灰常郁闷啊。
开始打的裸dfs,
结果最后一个点超时,
我尝试了好多剪枝和优化,
都不大管用,
在网上看的方法都不大懂,
尤其是那个对称的优化,最让我无语了。。。
于是我采用位运算的方法来计算方案数,
位运算部分完全参考M67牛的文章,
基本没有变化,具体原理说不清。。。
位运算部分参考M67牛的
http://www.matrix67.com/blog/archives/266
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | { ID: codeway3 PROG: checker LANG: PASCAL } program checker; type ll= array [ 1..15 , 1..15 ] of integer ; var i,j,n,bb,m,k,l,js: longint ; a:ll; b: array [ 1..13 ] of longint ; procedure doing(x,y: longint ;aa:ll); var i,j: longint ; begin if m> 3 then exit; for i:= 1 to n do begin aa[x,i]:= 1 ; aa[i,y]:= 1 ; if i+y-x in [ 1.. n] then aa[i,i+y-x]:= 1 ; if x+y-i in [ 1.. n] then aa[i,x+y-i]:= 1 ; end ; b[x]:=y; if x=n then begin if m< 3 then begin for i:= 1 to n- 1 do write (b[i], ' ' ); writeln (b[n]); end ; inc(m); b[x]:= 0 ; exit; end ; for i:= 1 to n do if aa[x+ 1 ,i]= 0 then doing(x+ 1 ,i,aa); b[x]:= 0 ; end ; procedure test(row,ld,rd: longint ); var pos,p: longint ; begin if row<>js then begin pos:=js and not (row or ld or rd); while pos<> 0 do begin p:=pos and -pos; pos:=pos-p; test(row+p,(ld+p)<< 1 ,(rd+p)>> 1 ); end ; end else inc(m); end ; begin assign(input, 'checker.in' ); reset(input); assign(output, 'checker.out' ); rewrite(output); readln(n); m:= 0 ; for i:= 1 to n do doing( 1 ,i,a); m:= 0 ; js:=( 1 <<n)- 1 ; test( 0 , 0 , 0 ); writeln (m); close(input); close(output); end . |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?