zoukankan      html  css  js  c++  java
  • 等差数列 [USACO Training Section 1.4]

    题目描述
    一个等差数列是一个能表示成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。

    输出格式:
    如果没有找到数列,输出`NONE’。
    如果找到了,输出一行或多行, 每行由二个整数组成:a,b。
    这些行应该先按b排序再按a排序。
    所求的等差数列将不会多于10,000个。

    输入样例#1:
    5
    7

    输出样例#1:
    1 4
    37 4
    2 8
    29 8
    1 12
    5 12
    13 12
    17 12
    5 20
    2 24

    //结构体+sort会超时
    //必须用二维数组+qsort
    #include<cstdio>
    int n,m;
    bool f[100001];
    int a[100001],b[100001],c[100001];
    int l=0;
    void qsort(int l,int r)
    {
            int i=l,j=r,t,mid1=b[(l+r)/2],mid2=a[(l+r)/2];
            do
            {
                    while(b[i]<mid1||(b[i]==mid1&&a[i]<mid2))i++;
                    while(b[j]>mid1||(b[j]==mid1&&a[j]>mid2))j--;
                    if(i<=j)
                    {
                            t=a[i];a[i]=a[j];a[j]=t;
                            t=b[i];b[i]=b[j];b[j]=t;
                            i++;j--;
                    }
            }while(i<=j);
            if(l<j)qsort(l,j);
            if(i<r)qsort(i,r);
    }
    int main()
    {
            scanf("%d%d",&n,&m);
            int i,j,cs=0,t,ans;
            for(i=0;i<=m;i++)//枚举小于m的平方数 
                for(j=i;j<=m;j++)
                    if(!f[i*i+j*j])//该数没被记录 
                    {
                        f[i*i+j*j]=1;//标记 
                        cs++;//记录总数 
                        c[cs]=i*i+j*j;
                    }
            for(i=1;i<=cs;i++)//枚举a的值(a肯定是双平方数)
                for(j=1;j<=2*m*m;j++)//枚举b的值(肯定不超过2m^2(a,b<=m^2)) 
                {
                    if(c[i]+(n-1)*j>2*m*m)    break;//数列最后一个要在范围内 
                    ans=1;
                    for(int k=1;ans<n;k++)//满足就累计,不满足跳出 
                    {    
                        if(f[c[i]+k*j])ans++;
                        else break;
                    } 
                    if(ans==n)//满足就累计 
                    {
                        l++;a[l]=c[i];b[l]=j;
                    }
                }
    
            if(l==0)
            {printf("NONE
    ");return 0;}//无数据便直接输出结束 
            qsort(1,l);
            for(i=1;i<=l;i++)
                printf("%d %d
    ",a[i],b[i]);
            return 0;
    }
  • 相关阅读:
    【蓝桥杯/算法训练】Sticks 剪枝算法 (附胜利大逃亡)
    【蓝桥杯/基础练习】回文数、特殊的回文数
    【蓝桥杯/基础练习】十六进制转八进制
    交叉验证
    第一次写博客---交叉验证
    实验五
    汇编语言第二章
    实验四
    实验三
    实验二
  • 原文地址:https://www.cnblogs.com/ibilllee/p/7651977.html
Copyright © 2011-2022 走看看