USACO 1.4 - Arithmetic Progressions(DFS)

An arithmetic progression is a sequence of the form a, a+b,a+2b, ..., a+nb where n=0,1,2,3,... . For this problem, a is anon-negative integer and b is a positive integer.

Write a program that finds all arithmetic progressions of lengthn in the set S of bisquares. The set of bisquares is defined as theset of all integers of the form p2 + q2 (wherep and q are non-negative integers).

TIME LIMIT: 5 secs

PROGRAM NAME: ariprog

INPUT FORMAT

Line 1:N (3 <= N <= 25), the length of progressions for which to search
Line 2:M (1 <= M <= 250), an upper bound to limit the search to the bisquares with 0 <= p,q <= M.

SAMPLE INPUT (file ariprog.in)

5
7

OUTPUT FORMAT

If no sequence is found, a singe line reading `NONE'. Otherwise,output one or more lines, each with two integers: the first element ina found sequence and the difference between consecutive elements in thesame sequence. The lines should be ordered with smallest-differencesequences first and smallest starting number within those sequencesfirst.

There will be no more than 10,000 sequences.

SAMPLE OUTPUT (file ariprog.out)

1 4
37 4
2 8
29 8
1 12
5 12
13 12
17 12
5 20
2 24

                                           

题意:

n 个等差数列中的数,输入m,每一个数都可以用p.q(0<=p,q<=m) 表示。求出满足要求的等差数列,输出首数和等差。

思路:

暴力枚举 + 减枝。先记录p , q可以组成什么数,然后枚举每一个数,枚举等差(这里需要减枝,等差×(n-1)+num[i]<= m*m*2),使用DFS 判断是否能得到n 个数。

CODE ;

/*
ID: sotifis3
LANG: C++
TASK: ariprog
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;

set<int> s;
struct node
{
    int x, y;
}ans[10005];
int cnt, n, m;
int vis[125050], num[62550];

bool cmp(node p, node q)
{
    if(p.y == q.y) return p.x < q.x;
    return p.y < q.y;
}
void dfs(int dth, int a, int b, int nn)
{
    if(dth == n){
        ans[cnt].x = a;
        ans[cnt].y = b;
        cnt++;
        return;
    }
    if(vis[nn + b]) dfs(dth+1, a, b, nn + b);
    else return;
}
int main()
{
    freopen("ariprog.in","r",stdin);
    freopen("ariprog.out","w",stdout);
    cnt = 0;
    int k = 0;
    scanf("%d %d", &n, &m);
    for(int i = 0; i <= m; ++i){
        for(int j = 0; j <= m; ++j){
            if(!vis[i*i+j*j]){
                vis[i*i + j*j] = 1;
                num[k++] = i*i+j*j;
            }
        }
    }
    for(int i = 0; i < k; ++i){
        int mm = m*m*2 - num[i];
        for(int j = 1; j*(n - 1) <= mm; ++j){
            if((j*(n - 1) + num[i]) <= m*m*2)
            dfs(1, num[i], j, num[i]);
        }
    }
    if(cnt == 0) printf("NONE\n");
    else {
        sort(ans, ans + cnt, cmp);
        for(int i = 0; i < cnt; ++i){
            printf("%d %d\n", ans[i].x, ans[i].y);
        }
    }

    return 0;
}



 





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值