1. 程式人生 > >和小哥哥一起刷洛谷(1)

和小哥哥一起刷洛谷(1)

最小公倍數 memset actor 插入 tor clas 插入代碼 c++ 英文

小哥我是編程愛好者,正在學習摸索中,此文就是我最近編的代碼以及編程中的思路,易錯點等心得體會。

今天小哥我作為cpp黨就來帶大家刷幾道很有意思的題目。

由於微信不支持插入代碼,只能用markdown寫文章,markdown的排版功能尚不熟悉,小試一下。

P1029最大公約數和最小公倍數問題

題目:

輸入 2 個正整數x0,y0,求出滿足下列條件的 P,Q 的個數
條件:
P,Q 是正整數
要求:
P,Q 以 x0 為最大公約數,以 y0 為最小公倍數.
試求:滿足條件的所有可能的 2 個正整數的個數.

思路:

1.枚舉a/y0的值

代碼:

#include<bits/stdc++.h>
using namespace std;
int main()
{
        int x,y,a,factors,count=0;
        cin>>x>>y;
        a=y/x;
        for(int i=1;i<=y;i++)
        {
            if(a%i==0)
            {   factors=0;
                for(inti2=2;i2<=min(i,a/i);i2++)
                {
                    if(i%i2==0 &&(a/i)%i2==0)
                    factors++;
                }
                if(factors==0)
                    count++;
            }
        }
        cout<<count;
        return 0;
}

P2118比例簡化

題目:

在社交媒體上,經常會看到針對某一個觀點同意與否的民意調查以及結果。例如,對某一觀點表示支持的有 1498 人,反對的有 902 人,那麽贊同與反對的比例可以簡單的記為 1498:902 。
不過,如果把調查結果就以這種方式呈現出來,大多數人肯定不會滿意。因為這個比例的數值太大,難以一眼看出它們的關系。對於上面這個例子,如果把比例記為 5:3,雖然與真實結果有一定的誤差,但依然能夠較為準確地反映調查結果,同時也顯得比較直觀。
現給出支持人數A,反對人數 B ,以及一個上限 L,請你將 A 比 B 化簡為 A’比 B’,要求在 A’和 B’均不大於 L 且 A’和 B’互質(兩個整數的最大公約數是 1 )的前提下, A’/B’ ≥ A/B且 A’/B’ - A/B的值盡可能小。

思路:

枚舉每個小於l的A和B,看哪個即大於又最接近A/B;

代碼:

#include<bits/stdc++.h>
using namespace std;
int main()
{
       int a,b,c;
       double s=10000,s1,s2;
       cin>>a>>b>>c;
       s1=1;s2=1;

       for(int i1=1;i1<=c;i1++)
       {
           for(int i2=1;i2<=c;i2++)
           {
              if((double)i1/i2<(double)a/b)continue;
              int m=i1;
              int n=i2;
              while(n!=0)
              {
                  int yu=m%n;
                  m=n;
                  n=yu;
              }
              if(m!=1) continue;
              if(s!=min(s,(double)i1/i2))
              {
                  s=(double)i1/i2;
                  s1=i1;s2=i2;
              }
           }
       }
       cout<<s1<<""<<s2;
       return 0;
}

易錯點:

雙重循環中if語句太多,小哥我其中有一個if語句第一次寫時只套了一條語句,偷懶,沒有寫花括號;結果後來又加了一條語句結果忘記補上花括號,導致程序錯亂,檢查了好久才檢查出來。

P1147 連續自然數和

題目:

對一個給定的自然數 M ,求出所有的連續的自然數段,這些連續的自然數段中的全部數之和為 M 。
例子: 1998+1999+2000+2001+2002= 10000 ,所以從 1998 到 2002 的一個自然數段為 M=10000 的一個解。

思路:

利用等差數列公式,枚舉項數n,判斷2m是否能被n整除以及(2num/n+1-n)整除2,並且(2num/n+1-n)/2>0。若符合,則輸出首項和末項。

代碼:

#include<bits/stdc++.h>
using namespace std;
int main()
{
        cin>>num;

        for(n=num;n>1;n--)
        {
            if(2*num%n==0 &&(2*num/n+1-n)%2==0 && (2*num/n+1-n)/2>0)
            {
                a=(2*num/n+1-n)/2;
                cout<<a<<" "<<a+n-1<<endl; 
            }
        }

        return 0;
}

易錯點:

1.題目要求輸出的兩個數之間用空格隔開,但是是英文空格!英文空格!英文空格!小哥我就在這裏錯了!!!

P1865 A%B problem

題目:

輸入一行兩個整數 詢問次數n,範圍m
接下來n行,每行兩個整數l,r表示區間
對於每次詢問輸出區間內質數個數t,如l或r?[1,m]輸出Crossing the line

思路1:

對範圍內所有數暴力試除,用布爾數組記錄數字是否為質數。
最後再檢測輸入的範圍內有多少個質數。
代碼如下:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int main()
{
        int n,m,a,b;
        cin>>n>>m;

        bool list[m+1];
        memset(list,false,sizeof(list));

        for(int i=2;i<=m;i++)
        {
            int count=0;
            for(int i1=2;i1<i;i1++)
            {
                if(i%i1==0) 
                {
                    count++;
                    break;
                }
            }
            if(count==0)
            {
                list[i]=true;
            }
        }

        for(int l=1;l<=n;l++)
        {
            cin>>a>>b;

            if(a<1 || b>m)
            {
                cout<<"Crossing theline"<<endl;
                continue;
            }

            int count=0;
            for(int i=a;i<=b;i++)
            {
                if(list[i]==true)
                {
                    count++;
                }
            }
            cout<<count<<endl;
        }
        return 0;
}

結果你知道的——超時!

思路2:

另一種選出質數的方法——刪掉合數,篩質數!
在布爾列表分別把
2的2倍,3倍,4倍……設為false;
再找到下一個為true的數M,把
M的 2倍,3倍,4倍……設為false;

代碼:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int main()
{

        int n,m,a,b;
        cin>>n>>m;

        bool list[m+1];
        memset(list,true,sizeof(list));

        list[1]=false;
        for(int i=2;i<=m;i++)
        {
            if(list[i]==true)
            {
                for(int i2=2*i;i2<=m;i2+=i)
                    list[i2]=false ;
            }
        }

        for(int l=1;l<=n;l++)
        {
            cin>>a>>b;

            if(a<1 || b>m)
            {
                cout<<"Crossing the line"<<endl;
                continue;
            }

            int count=0;
            for(int i=a;i<=b;i++)
            {
                if(list[i]==true)
                {
                    count++;
                }
            }
            cout<<count<<endl;
        }
        return 0;
}

終於沒超時!!

易錯點:

1.這題很容易超時,要多試幾種找質數的方法。

和小哥哥一起刷洛谷(1)