【USACO 1.4.3】等差数列

【题目描述】

一个等差数列是一个能表示成a, a+b, a+2b,..., a+nb (n=0,1,2,3,...)的数列。

在这个问题中a是一个非负的整数,b是正整数。写一个程序来找出在双平方数集合(双平方数集合是所有能表示成p的平方 + q的平方的数的集合)S中长度为n的等差数列。

【格式】

TIME LIMIT: 5 秒

INPUT FORMAT:

(file ariprog.in)

第一行: N(3<= N<=25),要找的等差数列的长度。

第二行: M(1<= M<=250),搜索双平方数的上界0 <= p,q <= M。

OUTPUT FORMAT:

(file ariprog.out)

如果没有找到数列,输出`NONE‘。

如果找到了,输出一行或多行, 每行由二个整数组成:a,b。

这些行应该先按b排序再按a排序。

所求的等差数列将不会多于10,000个。

【分析】

注意到时间限制是5秒,考虑用枚举。

我们能够很自然的想到把S中的数全部预处理出来,存在S数组中,然后再排一下序。

做一个两重循环来枚举数列的第一项和第二项,以两项之差找等差数列,最后查看是否有n个。

但是遗憾的是,即便是这样的方法还是会超时。

原因在哪里呢?

没错,就在于循环上,可以打表查看的是,当M上界一大了以后,S中的元素往往会有上千个。

但是在枚举的过程中,有一些枚举是完全可以舍弃掉的。

if (S[i]+(S[j]-S[i])*(n-1)>S[point-1]) continue;(这个便是最重要的剪枝)

把它加上去就能AC了。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <algorithm>
 6 const int maxs=250*250+10;
 7 using namespace std;
 8 struct Ans
 9 {
10        int a,d;//首项与公差
11        bool operator <(const Ans&b)const
12        {
13             if (b.d==d) return a<b.a;
14             return d<b.d;
15        }
16 }ans[10005*3];
17 int S[maxs],n,m,point=0,ans_point=0;
18 bool vis[maxs*2];
19 int main()
20 {
21     int i,j,k;
22     //文件操作
23     freopen("ariprog.in","r",stdin);
24     freopen("ariprog.out","w",stdout);
25     memset(vis,0,sizeof(vis));
26
27     scanf("%d%d",&n,&m);
28     for (i=0;i<=m;i++)
29     for (j=0;j<=m;j++)
30     if (vis[i*i+j*j]==0)
31     {
32          S[point++]=i*i+j*j;
33          vis[i*i+j*j]=1;
34     }
35     sort(S,S+point);//排序
36
37     for (i=0;i<point;i++)
38     for (j=i+1;j<point;j++)
39     {
40         if (S[i]+(S[j]-S[i])*(n-1)>S[point-1]) continue;
41         int last=S[j],d=S[j]-S[i],cnt=2;
42         while (vis[last+d] && last+d<=S[point-1] && cnt<n) {cnt++;last=last+d;}
43         if (cnt==n)
44         {
45             ans[ans_point].a=S[i];
46             ans[ans_point++].d=d;
47         }
48     }
49     //排序后输出
50     sort(ans,ans+ans_point);
51     if (ans_point==0) printf("NONE\n");
52     else
53     {
54          for (i=0;i<ans_point;i++)
55          printf("%d %d\n",ans[i].a,ans[i].d);
56     }
57     return 0;
58 }

【USACO 1.4.3】等差数列

时间: 2024-10-13 22:18:17

【USACO 1.4.3】等差数列的相关文章

USACO Arithmetic Progressions 【构造等差数列】

USER: Jeremy Wu [wushuai2] TASK: ariprog LANG: C++ Compiling... Compile: OK Executing... Test 1: TEST OK [0.005 secs, 11880 KB] Test 2: TEST OK [0.008 secs, 11880 KB] Test 3: TEST OK [0.008 secs, 11876 KB] Test 4: TEST OK [0.014 secs, 11880 KB] Test

洛谷P1214 [USACO1.4]等差数列 Arithmetic Progressions

P1214 [USACO1.4]等差数列 Arithmetic Progressions• o 156通过o 463提交• 题目提供者该用户不存在• 标签USACO• 难度普及+/提高 提交 讨论 题解 最新讨论• 这道题有问题• 怎么进一步优化时间效率啊 …题目描述一个等差数列是一个能表示成a, a+b, a+2b,..., a+nb (n=0,1,2,3,...)的数列.在这个问题中a是一个非负的整数,b是正整数.写一个程序来找出在双平方数集合(双平方数集合是所有能表示成p的平方 + q的平

luogu P1214 [USACO1.4]等差数列 Arithmetic Progressions

题目描述 一个等差数列是一个能表示成a, a+b, a+2b,..., a+nb (n=0,1,2,3,...)的数列. 在这个问题中a是一个非负的整数,b是正整数.写一个程序来找出在双平方数集合(双平方数集合是所有能表示成p的平方 + q的平方的数的集合,其中p和q为非负整数)S中长度为n的等差数列. 输入输出格式 输入格式: 第一行: N(3<= N<=25),要找的等差数列的长度. 第二行: M(1<= M<=250),搜索双平方数的上界0 <= p,q <= M

洛谷 P1214 [USACO1.4]等差数列 Arithmetic Progressions

题目描述 一个等差数列是一个能表示成a, a+b, a+2b,..., a+nb (n=0,1,2,3,...)的数列. 在这个问题中a是一个非负的整数,b是正整数.写一个程序来找出在双平方数集合(双平方数集合是所有能表示成p的平方 + q的平方的数的集合,其中p和q为非负整数)S中长度为n的等差数列. 输入输出格式 输入格式: 第一行: N(3<= N<=25),要找的等差数列的长度. 第二行: M(1<= M<=250),搜索双平方数的上界0 <= p,q <= M

【USACO】ariprog

输入 : N  M 要找到长度为 N 的等差数列,要求数列中每个数字都可以表达成 a^2 + b^2 的和, 数字大小不超过M^2 + M^2 输出: 等差数列首元素 间隔 (多组答案分行输出) 解题思路:因为等差数列的数字都是平房和数  所以先生成所有的 从0 - M^2 + M^2的平方和数 去掉相同的并从小到大排序 然后对 所有间隔 . 首元素 做循环 判断能否找到以该首元素和间隔为条件的其他N-1个需要的数字 可以就存成答案: 提交后超时了.... test 5的时候 超了5s 正在想简

COGS 696. [IOI1996][USACO 2.3] 最长前缀

★   输入文件:prefix.in   输出文件:prefix.out   简单对比时间限制:1 s   内存限制:128 MB 描述 USACO 2.3.1 IOI96 在生物学中,一些生物的结构是用包含其要素的大写字母序列来表示的.生物学家对于把长的序列分解成较短的序列(即元素)很感兴趣. 如果一个集合 P 中的元素可以通过串联(元素可以重复使用,相当于 Pascal 中的 “+” 运算符)组成一个序列 S ,那么我们认为序列 S 可以分解为 P 中的元素.元素不一定要全部出现(如下例中B

USACO prefix TrieTree + DP

/* ID:kevin_s1 PROG:prefix LANG:C++ */ #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <vector> #include <map> #include <set> #include <algorithm> #include <cstdlib>

【USACO 1.3.4】牛式

[題目描述 ] 下面是一个乘法竖式,如果用我们给定的那n个数字来取代*,可以使式子成立的话,我们就叫这个式子牛式. * * * x * * ---------- * * * * * * ---------- * * * * 数字只能取代*,当然第一位不能为0,况且给定的数字里不包括0. 注意一下在美国的学校中教的"部分乘积",第一部分乘积是第二个数的个位和第一个数的积,第二部分乘积是第二个数的十位和第一个数的乘积. 写一个程序找出所有的牛式. [格式] INPUT FORMAT: (f

51nod1055 最长等差数列

基准时间限制:2 秒 空间限制:262144 KB 分值: 80 N个不同的正整数,找出由这些数组成的最长的等差数列. 例如:1 3 5 6 8 9 10 12 13 14 等差子数列包括(仅包括两项的不列举) 1 3 5 1 5 9 13 3 6 9 12 3 8 13 5 9 13 6 8 10 12 14 其中6 8 10 12 14最长,长度为5. Input 第1行:N,N为正整数的数量(3 <= N <= 10000). 第2 - N+1行:N个正整数.(2<= A[i] &