東華 OJ 一維陣列競賽 等差數列

Pure_Silly發表於2020-12-04

心路歷程和程式碼更改盡在註釋中

因為正好在學STL,所以故意用容器來寫的。但是因為不熟所以光寫程式碼就挺久了。

問題描述:

  1. 第一個問題:問題如何拆分。
  2. 第二個問題:選擇什麼容器完成。
  3. 第三個問題:如何使用容器(bushi
  4. 第四個問題:如何設定第一優先和第二優先排序
  5. 第五個問題:迴圈寫多了tle怎麼破。

AC程式碼(含修改前程式碼於註釋中)

#include <bits/stdc++.h>
#include <set>

using namespace std;

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    /*需求:
    * 找滿足n的等差數列且b為第一優先,a為第二優先輸出
    * 沒找到輸出NONE
    * 實現方法:
    * 首先以m為上限找到所有雙平方數的集合(集合不能有重複元素)->set
    * 依次判斷a_1、a_2···是否在set容器內有符合的元素//tle
    * 如果有繼續判斷,直至滿足n個元素//tle
    * 如果無則break掉
    * 由題意,不會有任意n,m,使得a_n=a_m
    */
    set <int> s;
    for(int i=0;i<=m;i++){//set自動去重,排序
        for(int j=0;j<=m;j++){
            s.insert(i*i+j*j);
        }
    }
    vector<int> vec(62501,0);
    for(auto itr:s){
        vec[itr]++;
    }
    int c=0;//count
    //rbegin();訪問最後一個元素的迭代器
    for(int k=1;k<=2*m*m/(n-1);k++){//公差
        for(set <int>::iterator it= s.begin();it!=s.end();it++){//第一項
            if((*it)+(n-1)*k>*(s.rbegin())){break;}//以這個為第一項的最後一項已經超出
            bool flag =1;
            for(int time =0;time<n;time++){
                if(!vec[(*it)+time*k]){
                    flag=0;
                    break;
                }
                // if(lower_bound(s.begin(),s.end(),(*it)+time*k)==s.end()){flag=0;break;}
                // if(*(lower_bound(s.begin(),s.end(),(*it)+time*k))!=(*it)+time*k){flag=0;break;}
                //if(s.find((*it)+time*k)==s.end()){flag=0;break;}//O(nlogn)
                //p.push_back(make_pair<int,int>(k,i));//make_pair只能常量賦值?
            }
            if(flag){//迴圈本身就升序
                cout<<*it<<" "<<k<<endl;
                c++;
            }
        }
    }
    if(c==0){
        cout<<"NONE"<<endl;
    }
    system("pause");
    return 0;
}

過程:

  1. 第一個問題如註釋,我拆分為了計算並儲存這個兩平方數和的集合以及遍歷查詢是否每一項都在這個集合內。
  2. 第二個問題,既然集合肯定set。
  3. 第三個問題:百度。
  4. 第四個問題:原本是打算用vector <pair<int,int>> vec;來儲存並用sort()函式排序的。但是vsc給我說輸入的引數不對?(用常量1,2不報錯,用a,b變數就報錯了)。然後就放棄了。後面改用迴圈解決(將外層迴圈的自變數設定為第一優先的變數,中間層為第二優先再輸出即可)。
  5. 第五個問題:原本是三重迴圈+find()函式來判斷該數是否存在於集合或者用三重迴圈+lower_bound()函式來實現此功能(因為lower_bound()函式理論上更快)但是反而用前者tle少一,不解。(兩種程式碼均在註釋)後面改為之前做過的計數的方法,另新建一個動態陣列,然後把set容器內元素的值作為下標,動態陣列存放該下標元素有的個數。如此就不必使用迴圈或其他函式就能快速判斷該數是否在集合內。

相關文章