PATの一般的な数学の問題-基本的な記事

目次

1.最大公約数と最小公倍数

最大公約数

最小公倍数

 

2.分数の4つの算術

スコア表現

分数の削減

分数の演算

スコア出力

3.素数の問題

4.素因数分解

 

詳細については、ピットを残してください

5.大きな整数演算

 

6.拡張ユークリッドアルゴリズム

 

 

7.組み合わせの数


 

 


1.最大公約数と最小公倍数


最大公約数

定義:最大公約数とは、2つの数値の間のすべての公約数の中で最大公約数を指します。

例:4と6の最大公約数は2、3と9の最大公約数は3です。

表現:gcd(a、b)、aとbの最大公約数表すために一般的に使用されます。

計算方法:一般的に使用されるユークリッドアルゴリズム、つまり、トス、ターン、除算。

定理に基づく:aとbが両方とも正の整数であるとすると、gcd(a、b)= gcd(b、a%b)となります。

具体的な実現:再帰的な形式で書かれています。

  1. 再帰:gcd(a、b)= gcd(b、a%b)
  2. 再帰境界:gcd(a、0)= a

(注:aとbのサイズの順序を考慮する必要はありません。再帰的な場合、a <bの場合、gcd操作の後に次のラウンドに持ち込まれる操作はgcd(b、a)であり、関数自体はスワップ操作を完了します。

int gcd(int a,int b)
{
    if(b==0) return a;
    else return gcd(b,a%b);
}


//或者,下面简洁写法


int gcd(int a,int b)
{
    return !b:a:gcb(b,a%b);
}

 

最小公倍数

定義:2つの正の整数のすべての共通倍数の中で最小公倍数。

例:4と6の最小公倍数は12、3と9の最小公倍数は9です。

表現:一般的に使用されるlcm(a、b)は、aとbの最小公倍数を表します。

計算方法:最大公約数を見つけることに基づいて、2つの数値を最大公約数で割った積が最小公倍数になります。

定理に基づく:aとbが両方とも正の整数であり、それらの最大公約数がd = gcb(a、b)であると仮定します。したがって、それらの最小公倍数は(a * b)/ d =(a * b)/ gcdです。 (a、b))

具体的な実装:最初にgcd関数を使用して最大公約数dを見つけ、次に2つの数値を乗算し、次にdを除算します。オーバーフローを防ぐために、最初の除算を使用してから乗算します(dは公約数であるため、すべての除算は整数として決定されます)。

int gcd(int a,int b)
{
    return !b:a:gcb(b,a%b);
}

int lcm(int a,int b)
{    
    int d=gec(a,b);
    return a/d*b;
}

 

 

2.分数の4つの算術

(この分数の計算の良い例があります。詳細については、PATのグレードBの質問1034、有理数の4つの算術演算を 参照してください。)


スコア表現

構造を使用してスコアを保存できます

struct Fraction
{
    int up , down;
};

上は分子を表し、下は分母を表します。

これを使用するための3つの考慮事項があります。

  1. Downは負でない数であり、符号はupに格納されます。
  2. スコアが0の場合、up = 0およびdown = 1が指定されます。
  3. 分子と分母の最大公約数は1です。

 

分数の削減

分数化のいくつかの操作は次のとおりです。

  1. 分母が負に見える場合、分子と分母は同時に逆になります。
  2. 分子upが0の場合、分母は1です。
  3. 分子と分母の最大公約数が1でない場合、削減が必要です。つまり、分子と分母が最大公約数で除算されます。

簡略化の手順は次のとおりです。

Fraction reducation(Fraction result)
{
    if(result.down<0)
    {
        result.up= -result.up;
        result.down= -result.down;
    }
    if(result.up==0)
    {
        result.down=1;
    }
    else{
        int d=gcd(abs(result.up),abs(result.down));
        result.up /= d;
        result.down /= d;
    }
    return result;
}

 

分数の演算

小学生の操作を段階的に追うだけです。

添加

\ frac {a_1} {b_1} + \ frac {a_2} {b_2} = \ frac {a_1 * b_2 + a_2 * b_1} {b_1 * b_2}

減算

\ frac {a_1} {b_1}-\ frac {a_2} {b_2} = \ frac {a_1 * b_2-a_2 * b_1} {b_1 * b_2}

乗算

\ frac {a_1} {b_1} \ times \ frac {a_2} {b_2} = \ frac {a_1 * a_2} {b_1 * b_2}

分割

\ frac {a_1} {b_1} \ div \ frac {a_2} {b_2} = \ frac {a_1 * b_2} {a_2 * b_1}

スコア出力

スコアを出力するときは、次の点に注意してください。

  1. 出力する前にスコアを減らすことを忘れないでください。
  2. 分母が1の場合、それは整数であることを意味し、分子を直接出力します。
  3. 分子が分母よりも大きい場合、それは不適切な分数であり、整数部分を単純化することを検討できます。
  4. 上記の3点以外は、通常の出力を押してください。

 

3.素数の問題


nが素数であるかどうかを判断する場合、除数の選択は部分的に検証するだけでよく、nの平方根は切り捨てられ、検証はここで行われます。
(二乗する理由は、2つの数が乗算演算であり、加算すると除算になるためです。)

bool judge(int n)
{
    if(n<=1)return false;
int sqr=(int)sqrt(1.0*n);
for(int i=2;i<=sqr;i++)
    if(n%i==0)return false;
return true;
}

実際の操作では、素数が最初にテーブルに格納されることが多く、後で呼び出して検索すると便利です。

テーブルヒット操作は、次のように、ベクトル配列を使用して動的に格納できます。

vector<int> vi;
for(j=2;j<200001;j++)
if(judge(j))vi.push_back(j); 

4.素因数分解


数には複数の素因数が存在する可能性があるため、その数のすべての統計がその構造に追加されます

struct factor{
    int x , count;
}fac[10];

//fac[i]存的是第i个质因子的内容和计数

素因数を解くという考え方は、素数の考え方とほぼ同じです。平方根までたどることができます。平方根より大きい素因数がある場合は、それ自体であることを意味します。

数値がトラバースされるたびに、whileを使用して剰余を複数回取得し、更新して剰余を継続して取得すると、現在の素数を因子の数としてカウントできます。

 

詳細については、ピットを残してください

5.大きな整数演算


 

6.拡張ユークリッドアルゴリズム


 

 

7.組み合わせの数

おすすめ

転載: blog.csdn.net/qq_41962612/article/details/114657863