• USACO section 1.4.3 Arithmetic Progressions


    1. 枚举可以算出来,但是肯定超时,所以要剪枝,以等差数列a+nb说明;

    2. 几个可以剪枝的地方:b的范围是从1~2*m*m/(n-1);

        a的范围是0~2*m*m - (n-1) * b

    然后循环判断是不是pq了

    剪枝不是很充分,但是最慢3秒多给过了,哈哈

    3.以下是代码:

    /*
    ID: dollar4
    PROG: ariprog
    LANG: C++
    */
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    
    int main()
    {
        ofstream fout ("ariprog.out");
        ifstream fin ("ariprog.in");
        int is[125010], sum = 0, i, j, k, m, n;
        memset(is, 0, sizeof(is));
        fin >> n >> m;
        for (i = 0; i <= m; i++)
            for (j = 0; j <= m; j++)
            {
                is[i*i+j*j] = 1;
            }
        for (i = 1; i <= (2*m*m)/(n-1); i++)//等差数列a+nb中的b
        {
            int e = (2 * m * m) - (n - 1) * i;
            for (j = 0; j <= e; j++) //a
            {
                int flag = 0;
                for (k = j; k <= j + (n - 1) * i; k += i)
                {
                    if (!is[k])
                    {
                        flag = 1;
                        break;
                    }
                }
                if (flag == 0)
                {
                    fout << j << ' ' << i << endl;
                    sum++;
                }
            }
        }
        if (sum == 0)
            fout << "NONE" << endl;
    
        return 0;
    }
    

    4. 官方参考代码:

    This can be done by brute force, enumerating over all possible sequences. It has to be done a little carefully in order to get it to run in time, however.

    Precalculate the bisquares, first of all. Calculate both a sorted list of the bisquares, along with a boolean array saying whether each number between 1 and 125000 (the maximum bisquare possible, for p,q < 250) is a bisquare.

    Go through the skips in increasing order, starting at 1, and continuing along as the sequence starting at 1 with that skip doesn't exceed the maximum bisquare. For each bisquare, determine if the sequence starting at that location and with the current skip value consists of all of bisquares. If so, output it.

    Here is the solution of Felix Arends from Germany (modified by Iran's Saber Fadaee):

    #include <stdio.h>
    #include <assert.h>
    #include <string>
    
    using namespace std;
    
    // open files
    FILE *fin = fopen ("ariprog.in", "r");
    FILE *fout = fopen ("ariprog.out", "w");
    
    // global variables
    unsigned int N, M, maxMM;
    unsigned int numbers [65000];
    unsigned int number_size = 0;
    unsigned char num_available [125001];
    unsigned char dist_available [125001];
    int have_res = 0;
    int skipstep = 1;
    
    // read the input
    
    int read_input () {
        fscanf (fin, "%d %d", &N, &M);
        return 0;
    }
    
    int cmp_int (const void *a, const void *b) {
        return (*(int *)a - *(int *)b);
    }
    
    void asm_num (int a, int b) {
        for (unsigned int n = 1; n < N; n++)
            if (num_available [a + n * b] == 0) return;
    
        fprintf (fout, "%d %d\n", a, b);
        have_res ++;
        if (have_res==1)
            skipstep = b;
    
    }
    
    void asm_num () {
        for (unsigned int b = 1; b < maxMM; b+=skipstep) {
            if (dist_available [b]) {
                for (unsigned int p = 0; p < number_size && numbers [p] + (N -
    1) * b <= maxMM; p++)
                    asm_num (numbers [p], b);
            }
        }
    }
    
    int process () {
        memset (num_available, 0, sizeof (unsigned char) * 125001);
        memset (dist_available, 0, sizeof (unsigned char) * 125001);
    
        for (unsigned int m1 = 0; m1 <= M; m1++) {
            for (unsigned int m2 = m1; m2 <= M; m2++) {
                int n = m1 * m1 + m2 * m2;
    
                if (!num_available [n]) {
                    num_available [n] = 1;
                    numbers [number_size++] = n;
                }
            }
        }
    
        qsort (numbers, number_size, sizeof (unsigned int), cmp_int);
    
        maxMM = M * M + M * M;
        for (unsigned int n1 = 0; n1 < number_size; n1++) {
            unsigned int _n1 = numbers [n1];
            for (unsigned int n2 = n1 + 1; n2 < number_size && _n1 + (numbers
    [n2] - _n1) * (N - 1) <= maxMM; n2++) {
                assert (numbers [n2] - _n1 >= 0 && numbers [n2] - _n1 < 125001);
                if (num_available [_n1 + (numbers [n2] - _n1) * (N - 1)] &&
                    num_available [_n1 + (numbers [n2] - _n1) * (N - 2)])
                    dist_available [numbers [n2] - _n1] = true;
            }
        }
    
        asm_num ();
    
        if (!have_res) fprintf (fout, "NONE\n");
    
        return 0;
    }
    
    int main () {
        read_input ();
        process ();
        fclose (fin);
        fclose (fout);
        return 0;
    }

    Here is an even faster solution of "UaE ProGrammeR":

    #include <fstream>
    #include <iostream>
    
    using namespace std;
    void quicksort (int[], int ,int);
    int pivotlist (int[], int,int);
    
    ofstream out ("ariprog.out");  
    
    int n;
    int main () {
        ifstream in ("ariprog.in");       
                                
        bool array[125001] = {false}, noneF;
        int m, upper, upperdef, def, p; 
        int places[300000], pl = 0;
        noneF = true;
        
        in>>n>>m;
        
        for (int i = 0; i <= m; i++)
            for (int j = 0; j <= m; j++) {
                if (!array[i*i+j*j]) {
                    places[pl] = i*i+j*j;   //Saving generated numbers
                    pl++;
                }
                array[i*i+j*j] = true;
            }
        
        upper = 2*m*m;
        upperdef = upper/(n-1);
        
        quicksort (places, 0, pl-1);
        
        for ( def = 1; def<=upperdef; def++) // Loop to check for solutions
                                           // It looks for solutions in
                                           // correct order so you 
                                           // print the solution directly
                                           // without sorting first, thnx to who said:
                                           // Trade Memory for Speed !!
        {
            for ( p = 0; places[p]<=(upper-((n-2)*def)); p++) {
                bool is;
                is = true;
                int where;
    
                for (int c = (n-1); c>=0 ; c--)
                        if (!array[places[p]+c*def]) {
                            is = false;
                            where = (p+c*def);
                            break;
                        }
        
                if (is) {
                    noneF = false;
                    out<<places[p]<<" "<<def<<endl;
                }
            }
        }
        
        if (noneF)
            out<<"NONE"<<endl;
        
        return 0;
    }
    
    void quicksort (int array[], int start, int last) {
        int pivot;
        if (start < last) {
            pivot = pivotlist(array, start,last);
            quicksort (array, start,pivot-1);
            quicksort (array, pivot+1,last);
        }
    }
    
    int pivotlist(int array[], int f, int l) {
        int pivotpoint;
        int pivotvalue, temp;
        
        pivotvalue = array[f];
        pivotpoint = f;
        
        for (int i = f+1;i<=l; i++) {
           	if (array[i]<pivotvalue) {	
          	    pivotpoint++;
                temp = array[i];
                array[i] = array[pivotpoint];
                array[pivotpoint] = temp;
       	 }
       }
       temp = array[f];
       array[f] = array[pivotpoint];
       array[pivotpoint] = temp;
       
       return pivotpoint;
    }


  • 相关阅读:
    文件中的类都不能进行设计,因此未能为该文件显示设计器。设计器检查出文件中有以下类: FormMain --- 未能加载基类“WinForm.Win.FormsBase.FormMainBase”。请确保已引用该程序集并已生成所有项目
    Xcopy命令参数使用介绍
    c#生成方案里预生成拷贝文件
    visual studio 2010 出现问题,不能设置断点调试了,一运行就未响应,然后程序退出
    开启Visual Studio 2013时,出现Microsoft.VisualStudio.Web.PasteJson.JsonPackage无法载入的可能解決方案
    Java开发知识之XML文档使用,解析
    JAVA开发知识之Java的线程
    git版本控制工具的使用
    Java开发知识之Java的正则表达式
    PC逆向之代码还原技术,第一讲基本数据类型在内存中的表现形式.浮点,指针寻址公式
  • 原文地址:https://www.cnblogs.com/dollarzhaole/p/3188913.html
Copyright © 2020-2023  润新知