USACO 1.4 Arithmetic Progressions

按步长递增的顺序搜索,先预处理出所有可能的步长,及位置值(用flg[]标记),再深搜

预处理稍微有点麻烦

ContractedBlock.gif ExpandedBlockStart.gif code
 
   
1 /*
2 ID: superbi1
3 LANG: C++
4 TASK: ariprog
5   */
6 #include < iostream >
7 #include < fstream >
8 #include < string >
9 #include < stdlib.h >
10 #define NL 250
11 using namespace std;
12
13 int f0[NL * NL], nf; // 起始点
14 int dis[NL * NL], nd; // 步长
15 bool flg[NL * NL * 2 + 1 ], flg1[NL * NL * 2 + 1 ];
16 bool yes;
17
18 ifstream fin( " ariprog.in " );
19 ofstream fout( " ariprog.out " );
20
21 int cmp( const void * a, const void * b)
22 {
23 return * ( int * )a - * ( int * )b;
24 }
25
26 void init( int m)
27 {
28 int i, j, t;
29 nf = 0 ;
30 fill_n(flg, m * m * 2 , 0 );
31 for (i = 0 ; i <= m; i ++ ) {
32 for (j = 0 ; j <= m; j ++ ) {
33 t = i * i + j * j;
34 if ( ! flg[t]) {
35 flg[t] = 1 ;
36 f0[nf ++ ] = t;
37 }
38 }
39 }
40 qsort(f0, nf, sizeof (f0[ 0 ]), cmp);
41 fill_n(flg1, m * m * 2 , 0 );
42 nd = 0 ;
43 for (i = 0 ; i < nf; i ++ ) {
44 for (j = i + 1 ; j < nf; j ++ ) {
45 t = f0[j] - f0[i];
46 if (t > 4167 ) break ;
47 if ( ! flg1[t]) {
48 flg1[t] = 1 ;
49 dis[nd ++ ] = t;
50 }
51 }
52 }
53 qsort(dis, nd, sizeof (dis[ 0 ]), cmp);
54 }
55
56 void DFS( int a, int b, int lev, int n)
57 {
58 if (lev == n) {
59 yes = true ;
60 fout << a << ' ' << b << endl;
61 return ;
62 }
63 if (flg[a + b * lev]) DFS(a, b, lev + 1 , n);
64 }
65
66 void search( int n, int m)
67 {
68 int i, j;
69 int a, b;
70 for (i = 0 ; i < nd; i ++ ) {
71 if (dis[i] * 2 > m * m * 2 ) break ;
72 for (j = 0 ; j < nf; j ++ ) {
73 a = f0[j];
74 b = dis[i];
75 if (a + 2 * b > m * m * 2 ) break ;
76 DFS(a, b, 0 , n);
77 }
78 }
79 }
80
81 int main()
82 {
83 int N, M;
84 yes = false ;
85 fin >> N >> M;
86 init(M);
87 search(N, M);
88 if ( ! yes) fout << " NONE " << endl;
89 return 0 ;
90 }

 

转载于:https://www.cnblogs.com/superbin/archive/2010/05/22/1741630.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值