• [Codeforces] number theory (R1200) Part.8


    [Codeforces] number theory (R1200) Part.8

    题单:https://codeforces.com/problemset/page/6?tags=number%20theory,0-1200

    1511B. GCD Length

    原题指路:https://codeforces.com/problemset/problem/1511/B

    题意 ( 2   s 2\ \mathrm{s} 2 s)

    给定三个整数 a , b , c a,b,c a,b,c,构造任两个正整数 x , y   s . t .   x x,y\ s.t.\ x x,y s.t. x的十进制表示(不含前导零,下同)包含 a a a个数码, y y y的十进制表示包含 b b b个数码, gcd ⁡ ( x , y ) \gcd(x,y) gcd(x,y)的十进制表示包含 c c c个数码.

    t    ( 1 ≤ t ≤ 285 ) t\ \ (1\leq t\leq 285) t  (1t285)组测试数据.每组测试数据输入三个整数 a , b , c    ( 1 ≤ a , b ≤ 9 , 1 ≤ c ≤ min ⁡ { a , b } ) a,b,c\ \ (1\leq a,b\leq 9,1\leq c\leq \min\{a,b\}) a,b,c  (1a,b9,1cmin{a,b}).数据保证有解.

    思路

    x = 1 0 ⋯ 0 ⏟ ( a − c ) 个 0 ⋯ 0 ⏟ ( c − 1 ) 个 , y = 1 1 ⋯ 1 ⏟ ( b − c ) 个 0 ⋯ 0 ⏟ ( c − 1 ) 个 x=1\underbrace{0\cdots 0}_{(a-c)个}\underbrace{0\cdots 0}_{(c-1)个},y=1\underbrace{1\cdots 1}_{(b-c)个}\underbrace{0\cdots 0}_{(c-1)个} x=1(ac) 00(c1) 00,y=1(bc) 11(c1) 00.因 gcd ⁡ ( 10 ⋯ 0 , 11 ⋯ 1 ) = 1 \gcd(10\cdots 0,11\cdots 1)=1 gcd(100,111)=1,故满足条件.

    代码

    void solve() {
    	int a, b, c; cin >> a >> b >> c;
        cout << "1" << string(a - 1, '0') << ' ' << string(b - c + 1, '1') << string(c - 1, '0') << endl;
    } 
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9


    1514A. Perfectly Imperfect Array

    原题指路:https://codeforces.com/problemset/problem/1514/A

    题意

    称一个序列是好的,如果它存在一个非空的子列使得其中元素之积不是完全平方数.

    t    ( 1 ≤ t ≤ 100 ) t\ \ (1\leq t\leq 100) t  (1t100)组测试数据.每组测试数据第一行输入一个整数 n    ( 1 ≤ n ≤ 100 ) n\ \ (1\leq n\leq 100) n  (1n100),表示序列长度.第二行输入 n n n个整数 a 1 , ⋯   , a n    ( 1 ≤ a i ≤ 1 e 4 ) a_1,\cdots,a_n\ \ (1\leq a_i\leq 1\mathrm{e}4) a1,,an  (1ai1e4).

    对每组测试数据,若序列 a [ ] a[] a[]是好的,输出"YES";否则输出"NO".

    思路

    注意到若序列 a [ ] a[] a[]中包含一个非完全平方数,则它是好的.

    代码

    bool check(int x) {
        int tmp = sqrt(x);
        return x == tmp * tmp;
    }
    
    void solve() {
    	int n; cin >> n;
    
        bool ok = false;
        while (n--) {
            int x; cin >> x;
            ok |= !check(x);
        }
        cout << (ok ? "YES" : "NO") << endl;
    } 
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20


    1515B. Phoenix and Puzzle

    原题指路:https://codeforces.com/problemset/problem/1515/B

    题意 ( 2   s 2\ \mathrm{s} 2 s)

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    n n n个如图(1)所示的等腰直角三角形的拼图,问能否用它们拼成一个正方形,使得所有的拼图都用完,若能则输出"YES";否则输出"NO".

    t    ( 1 ≤ t ≤ 1 e 4 ) t\ \ (1\leq t\leq 1\mathrm{e}4) t  (1t1e4)组测试数据.每组测试数据输入一个整数 n    ( 1 ≤ n ≤ 1 e 9 ) n\ \ (1\leq n\leq 1\mathrm{e}9) n  (1n1e9).

    思路

    如图(2)和图(3)所示,可用 2 2 2块或 4 4 4块拼图拼成一个小正方形.设小正方形的数量为 x x x,则用小正方先能拼成一个大正方形的充要条件是: x x x是完全平方数.

    有解的条件只能是下列两条件之一:① n n n 2 2 2的倍数,且 n 2 \dfrac{n}{2} 2n是完全平方数;② n n n 4 4 4的倍数,且 n 4 \dfrac{n}{4} 4n是完全平方数.

    [] 下面证明无其他解.设直角三角形的直角边长为 1 1 1,则斜边长为 2 \sqrt{2} 2 .

    设拼成的大正方形的边长用到了 a a a条直角边和 b b b条斜边,则其边长为 a + 2 b a+\sqrt{2}b a+2 b.

    注意到大正方形的面积 ( a + 2 b ) 2 \left(a+\sqrt{2}b\right)^2 (a+2 b)2是有理数,则 a = 0 a=0 a=0 b = 0 b=0 b=0.

    代码

    bool check(int x) {
        int tmp = sqrt(x);
        return x == tmp * tmp;
    }
    
    void solve() {
    	int n; cin >> n;
    
        bool ok = false;
        ok |= n % 2 == 0 && check(n / 2);
        ok |= n % 4 == 0 && check(n / 4);
        cout << (ok ? "YES" : "NO") << endl;
    } 
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18


    1520B. Ordinary Numbers

    原题指路:https://codeforces.com/problemset/problem/1520/B

    题意 ( 2   s 2\ \mathrm{s} 2 s)

    称一个整数是好的,如果它的所有数码都相同.

    t    ( 1 ≤ t ≤ 1 e 4 ) t\ \ (1\leq t\leq 1\mathrm{e}4) t  (1t1e4)组测试数据.每组测试数据输入一个整数 n    ( 1 ≤ n ≤ 1 e 9 ) n\ \ (1\leq n\leq 1\mathrm{e}9) n  (1n1e9),问 [ 1 , n ] [1,n] [1,n]中好的数的个数.

    思路

    注意到好的数可表示为 d ( 1 0 0 + 1 0 1 + ⋯ + 1 0 k ) d(10^0+10^1+\cdots+10^k) d(100+101++10k),则只需统计   s . t .   d ( 1 0 0 + 1 0 1 + ⋯ + 1 0 k ) ≤ n \ s.t.\ d(10^0+10^1+\cdots+10^k)\leq n  s.t. d(100+101++10k)n的整数对 ( d , k ) (d,k) (d,k)的个数,其中 d ∈ [ 1 , 9 ] , k ∈ [ 0 , 8 ] d\in[1,9],k\in[0,8] d[1,9],k[0,8],暴力统计即可.

    代码

    void solve() {
    	int n; cin >> n;
        
        int ans = 0;
        for (ll pow10 = 1; pow10 <= n; pow10 = pow10 * 10 + 1) {
            for (int d = 1; d <= 9; d++) 
                ans += pow10 * d <= n;
        }
        cout << ans << endl;
    }
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15


    1521A. Nastia and Nearly Good Numbers

    原题指路:https://codeforces.com/problemset/problem/1521/A

    题意

    给定两整数 A , B A,B A,B,①称一个整数是好的,如果它能被 A B AB AB整除;②称一个整数是近似好的,如果它能被 A A A整除.构造三个相异的正整数 x , y , z x,y,z x,y,z,使得其中恰有一个好的数、恰有两个近似好的数,且 x + y = z x+y=z x+y=z.

    t    ( 1 ≤ t ≤ 1 e 4 ) t\ \ (1\leq t\leq 1\mathrm{e}4) t  (1t1e4)组测试数据.每组测试数据输入两个整数 A , B    ( 1 ≤ A , B ≤ 1 e 6 ) A,B\ \ (1\leq A,B\leq 1\mathrm{e}6) A,B  (1A,B1e6).

    对每组测试数据,若有解,输出"YES"并输出满足条件的三个整数 x , y , z    ( 1 ≤ x , y , z ≤ 1 e 18 ) x,y,z\ \ (1\leq x,y,z\leq 1\mathrm{e}18) x,y,z  (1x,y,z1e18);否则输出"NO".

    思路

    B = 1 B=1 B=1时,被 A B AB AB整除即被 A A A整除,此时好的和近似好的等价,无解.

    B ≥ 2 B\geq 2 B2时,取 A + A B = A ( B + 1 ) A+AB=A(B+1) A+AB=A(B+1).

    代码

    void solve() {
    	int a, b; cin >> a >> b;
    
        if (b == 1) cout << "NO" << endl;
        else {
            cout << "YES" << endl;
            cout << a << ' ' << (ll)a * b <<' ' << (ll)a * (b + 1) << endl;
        }
    }
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14


    1525A. Potion-making

    原题指路:https://codeforces.com/problemset/problem/1525/A

    题意

    有A和B两种水,现要配置包含 k % k\% k%的A水和 ( 100 − k ) % (100-k)\% (100k)%的B水的水,每次操作可加 1 1 1单位的A水或B水,问最少操作次数.

    t    ( 1 ≤ t ≤ 100 ) t\ \ (1\leq t\leq 100) t  (1t100)组测试数据.每组测试数据输入一个整数 k    ( 1 ≤ k ≤ 100 ) k\ \ (1\leq k\leq 100) k  (1k100).

    思路

    首先必有解,最坏可加 k k k次A水和 ( 100 − k ) (100-k) (100k)次B水.

    设A水、B水分别加 x x x y y y次,则 x x + y = k 100 \dfrac{x}{x+y}=\dfrac{k}{100} x+yx=100k.显然 ( x + y ) ∣ 100 (x+y)\mid 100 (x+y)100,不妨设 z ( x + y ) = 100 z(x+y)=100 z(x+y)=100,则 z x = k zx=k zx=k,即 x = k z x=\dfrac{k}{z} x=zk.

    代入 z ( x + y ) = 100 z(x+y)=100 z(x+y)=100,解得 y = 100 − k z y=\dfrac{100-k}{z} y=z100k,则 a n s = x + y = 100 z ans=x+y=\dfrac{100}{z} ans=x+y=z100.

    x , a n s ∈ Z x,ans\in\mathbb{Z} x,ansZ,则 z ∣ k , z ∣ 100 z\mid k,z\mid 100 zk,z100.为使得 a n s ans ans最小,取 z = gcd ⁡ ( 100 , k ) z=\gcd(100,k) z=gcd(100,k).

    代码

    void solve() {
    	int k; cin >> k;
        cout << 100 / gcd(100, k) << endl;
    }
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9


    1535B. Array Reodering

    原题指路:https://codeforces.com/problemset/problem/1535/B

    题意

    对序列 a 1 , ⋯   , a n a_1,\cdots,a_n a1,,an称一对下标 ( i , j )    ( 1 ≤ i < j ≤ n ) (i,j)\ \ (1\leq i(i,j)  (1i<jn)是好的,如果 gcd ⁡ ( a i , 2 a j ) > 1 \gcd(a_i,2a_j)>1 gcd(ai,2aj)>1.将 a [ ] a[] a[]排序,使得其好的下标的对数最多,输出好的下标的对数.

    t    ( 1 ≤ t ≤ 1000 ) t\ \ (1\leq t\leq 1000) t  (1t1000)组测试数据.每组测试数据第一行输入一个整数 n    ( 2 ≤ n ≤ 2000 ) n\ \ (2\leq n\leq 2000) n  (2n2000).第二行输入 n n n个整数 a 1 , ⋯   , a n    ( 1 ≤ a i ≤ 1 e 5 ) a_1,\cdots,a_n\ \ (1\leq a_i\leq 1\mathrm{e}5) a1,,an  (1ai1e5).数据保证所有测试数据的 n n n之和不超过 2000 2000 2000.

    思路

    显然应将偶数排在前面,奇数排在后面.显然偶数间顺序无关.对奇数 a i , a j , gcd ⁡ ( a i , 2 a j ) = gcd ⁡ ( a i , a j ) a_i,a_j,\gcd(a_i,2a_j)=\gcd(a_i,a_j) ai,aj,gcd(ai,2aj)=gcd(ai,aj),故奇数间的顺序无关.

    代码

    void solve() {
    	int n; cin >> n;
    	vi a(n);
    	for (int& ai : a) cin >> ai;
    
    	sort(all(a), [&](const int& A, const int& B) {
    		return A % 2 < B % 2;
    		});
    
    	int ans = 0;
    	for (int i = 0; i < n; i++) {
    		for (int j = i + 1; j < n; j++)
    			ans += gcd(a[i], a[j] * 2) > 1;
    	}
    	cout << ans << endl;
    }
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21


    1541B. Pleasant Pairs

    原题指路:https://codeforces.com/problemset/problem/1541/B

    题意

    给定一个包含 n n n个相异整数的序列 a 1 , ⋯   , a n a_1,\cdots,a_n a1,,an,求使得 1 ≤ i < j ≤ n 1\leq i1i<jn a i ⋅ a j = i + j a_i\cdot a_j=i+j aiaj=i+j的整数对 ( i , j ) (i,j) (i,j)的对数.

    t    ( 1 ≤ t ≤ 1 e 4 ) t\ \ (1\leq t\leq 1\mathrm{e}4) t  (1t1e4)组测试数据.每组测试数据第一行输入一个整数 n    ( 2 ≤ n ≤ 1 e 5 ) n\ \ (2\leq n\leq 1\mathrm{e}5) n  (2n1e5).第二行输入 n n n个相异的整数 a 1 , ⋯   , a n    ( 1 ≤ a i ≤ 2 n ) a_1,\cdots,a_n\ \ (1\leq a_i\leq 2n) a1,,an  (1ai2n).数据保证所有测试数据的 n n n之和不超过 2 e 5 2\mathrm{e}5 2e5.

    思路

    注意到 a i ⋅ a j = i + j ≤ 2 n a_i\cdot a _j=i+j\leq 2n aiaj=i+j2n,可枚举每个 ( i + j ) (i+j) (i+j)的值后再枚举每个 a i a_i ai,检查是否存在满足条件的元素即可.

    满足上述条件的整数对 ( i , j ) (i,j) (i,j) O ( n log ⁡ n ) O(n\log n) O(nlogn)对.

    [] 设 a i = x a_i=x ai=x,则 a j a_j aj至多有 2 n x \dfrac{2n}{x} x2n种取值. ∑ i = 1 n 2 n i = 2 n ∑ i = 1 n 1 i = O ( n log ⁡ n ) \displaystyle\sum_{i=1}^n \dfrac{2n}{i}=2n\sum_{i=1}^n \dfrac{1}{i}=O(n\log n) i=1ni2n=2ni=1ni1=O(nlogn).

    代码

    void solve() {
    	int n; cin >> n;
      umap pos;  // 每个a_i的值所在的下标
      for (int i = 1; i <= n; i++) {
        int a; cin >> a;
        pos[a] = i;
      }
    
      int ans = 0;
      for (int i = 2; i <= 2 * n; i++) {  // 枚举i+j
        for (int j = 1; j * j < i; j++) {  // 枚举a[i],注意不是<=
          if (i % j ==  0) {
            int k = i / j;
            if (pos[j] && pos[k] && pos[j] + pos[k] == i) ans++;
          }
        }
      }
      cout << ans << endl;
    } 
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24


    1543A. Exciting Bets

    原题指路:https://codeforces.com/problemset/problem/1543/A

    题意

    给定两正整数 a , b a,b a,b.现有两种操作:① a + + , b + + a++,b++ a++,b++;② a − − , b − − a--,b-- a,b,此操作当且仅当 a , b > 0 a,b>0 a,b>0时可执行.问经过若干次(可能为零次)操作后 gcd ⁡ ( a , b ) \gcd(a,b) gcd(a,b)的最大值.

    t    ( 1 ≤ t ≤ 5000 ) t\ \ (1\leq t\leq 5000) t  (1t5000)组测试数据.每组测试数据输入两个整数 a , b    ( 0 ≤ a , b ≤ 1 e 18 ) a,b\ \ (0\leq a,b\leq 1\mathrm{e}18) a,b  (0a,b1e18).

    对每组测试数据,若 gcd ⁡ ( a , b ) \gcd(a,b) gcd(a,b)可达到无穷大,则输出"0 0";否则先输出 gcd ⁡ ( a , b ) \gcd(a,b) gcd(a,b)的最大值,再输出达到最大值所需的最小步数.

    思路

    a = b a=b a=b时,一直做操作①即可使得 gcd ⁡ ( a , b ) = I N F \gcd(a,b)=INF gcd(a,b)=INF.

    ②不妨设 a ≥ b a\geq b ab. gcd ⁡ ( a , b ) \gcd(a,b) gcd(a,b)能取得的最大值是 a − b a-b ab.

    ​ [] 注意到 gcd ⁡ ( a , b ) = gcd ⁡ ( a − b , b ) \gcd(a,b)=\gcd(a-b,b) gcd(a,b)=gcd(ab,b),其中 g = a − b g=a-b g=ab在操作过程中不变,

    ​ 为使得 gcd ⁡ ( a , b ) \gcd(a,b) gcd(a,b)最大,应通过操作将 b b b变为 g g g的倍数.

    ≤ b \leq b b的最大的 g g g的倍数是 ⌊ b g ⌋ ⋅ g \left\lfloor\dfrac{b}{g}\right\rfloor \cdot g gbg,则将 b b b减至该倍数所需步数为 b − ⌊ b g ⌋ ⋅ g = b % g b-\left\lfloor\dfrac{b}{g}\right\rfloor \cdot g=b\%g bgbg=b%g.

    ​ 显然将 b b b加至 ≥ b \geq b b的最小的 g g g的倍数所需步数为 g − b % g g-b\% g gb%g.

    代码

    void solve() {
    	ll a, b; cin >> a >> b;
        
      if (a == b) cout << "0 0" << endl;
      else {
        if (b > a) swap(a, b);
    
        ll g = a - b;
        cout << g << ' ' << min(b % g, g - b % g) << endl;
      }
    } 
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16


    1549A. Gregor and Cryptography

    原题指路:https://codeforces.com/problemset/problem/1549/A

    题意

    给定一个素数 p p p,求两个整数 a , b   s . t .   2 ≤ a < b ≤ p , p % a = p % b a,b\ s.t.\ 2\leq aa,b s.t. 2a<bp,p%a=p%b.

    t    ( 1 ≤ t ≤ 1000 ) t\ \ (1\leq t\leq 1000) t  (1t1000)组测试数据.每组测试数据输入一个素数 p    ( 5 ≤ p ≤ 1 e 9 ) p\ \ (5\leq p\leq 1\mathrm{e}9) p  (5p1e9).

    思路

    因素数 p ≥ 5 p\geq 5 p5,则 p p p是奇数,进而 ( p − 1 ) (p-1) (p1)是偶数.取 a = 2 , b = p − 1 a=2,b=p-1 a=2,b=p1即可.

    代码

    void solve() {
    	int n; cin >> n;
      cout << 2 << ' ' << n - 1 << endl;
    }
    
    int main() {
    	CaseT  // 单测时注释掉该行
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9


  • 相关阅读:
    三、微积分
    SpringCloud之nacos
    鸿蒙HarmonyOS实战-工具安装和Helloworld案例
    杰理之注册编码服务事件回调【篇】
    农产品商城毕业设计,农产品销售系统毕业设计,农产品电商毕业设计论文方案需求分析作品参考
    <C++> 模板-下
    坐标休斯顿,TDengine 受邀参与第九届石油天然气数字化大会
    图像练习-矩形4点OpenCV(01)
    你到底值多少钱?2023打工人薪酬指南
    CVE-2022-22954-VMware Workspace ONE Access SSTI远程代码执行流量特征
  • 原文地址:https://blog.csdn.net/Hytidel/article/details/126854180