【♂Not The Triumph♂O(∩_∩)O哈哈~But The Struggle♂】

竞赛决不是捷径,它只是另一种艰辛的生活方式。得到与失去,只有时间会去评判;成功与失败,只有历史能去仲裁。我不会永远成功,正如我不会永远失败一样

  C++博客 :: 首页 :: 联系 ::  :: 管理
  6 Posts :: 239 Stories :: 25 Comments :: 0 Trackbacks

常用链接

留言簿(7)

我参与的团队

搜索

  •  

积分与排名

  • 积分 - 104757
  • 排名 - 233

最新评论

阅读排行榜

评论排行榜

检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。
                                  列号

1  2  3  4  5  6

 -------------------------

1 |  | O |  |  |  |  |

 -------------------------

2 |  |  |  | O |  |  |

 -------------------------

3 |  |  |  |  |  | O |

 -------------------------

4 | O |  |  |  |  |  |

 -------------------------

5 |  |  | O |  |  |  |

 -------------------------

6 |  |  |  |  | O |  |

 -------------------------

上面的布局可以用序列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)

前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。


input:
6

output:
2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4

【参考程序】:
/*
ID: XIONGNA1
PROG: checker
LANG: C++
*/
#include
<iostream>
#include
<cstring>
using namespace std;
bool c[31],l[41],r[31];
int n,ans,temp[14];
void dfs(int x)
{
    
for (int y=1;y<=n;y++)
        
if (c[y+13&& l[y+x+13&& r[y-x+13])
        {
            temp[x]
=y;
            c[y
+13]=false;l[y+x+13]=false;r[y-x+13]=false;
            
if (x<n) dfs(x+1);
            
else 
            {
                
if (ans<3)
                {
                    
for (int i=1;i<=n-1;i++) printf("%d ",temp[i]);
                    printf(
"%d\n",temp[n]);
                }
                ans
++;
                
if (ans>14244)
                {
                    ans
+=59467;return ;
                }
            }
            c[y
+13]=true;l[y+x+13]=true;r[y-x+13]=true;
        }
}
int main()
{
    freopen(
"checker.in","r",stdin);
    freopen(
"checker.out","w",stdout);
    scanf(
"%d",&n);
    memset(c,
true,sizeof(c));
    memset(l,
true,sizeof(l));
    memset(r,
true,sizeof(r));
    ans
=0;   dfs(1);
    printf(
"%d\n",ans);
    
return 0;
}

【参考程序】://位运算 by Matrix67
var n,ans,m:longint;
procedure dfs(row,ld,rd:longint);
var pos,p:longint;
begin     
    
if row<>m then     
        begin       
            pos:
=m and not (row or ld or rd);       
            
while pos<>0 do       
                begin         
                     p:
=pos and -pos;        
                     pos:
=pos-p;         
                     dfs(row
+p,(ld+p)shl 1,(rd+p)shr 1);       
                end;     
        end     
        
else inc(ans);
end;
begin    
        assign(input,
'checker.in');reset(input);    
        assign(output,
'checker.out');rewrite(output);  
   
//while not eof do
        begin      
            readln(n);      
            m:
=(1 shl n)-1;      
            ans:
=0;      
            dfs(
0,0,0);      
            writeln(ans);  
    
//end; 
        close(input);close(output);
end.
posted on 2009-07-17 09:25 开拓者 阅读(319) 评论(0)  编辑 收藏 引用 所属分类: USACO 题解算法&例题经典习题

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理