[Codeforces] number theory (R1200) Part.7

[Codeforces] number theory (R1200) Part.7

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

1389A. LCM Problem

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

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

t    ( 1 ≤ t ≤ 1 e 4 ) t\ \ (1\leq t\leq 1\mathrm{e}4) t  (1t1e4)组测试数据.每组测试数据输入两个整数 l , r    ( 1 ≤ l < r ≤ 1 e 9 ) l,r\ \ (1\leq l<r\leq 1\mathrm{e}9) l,r  (1l<r1e9),问是否 ∃ x , y ∈ Z   s . t .    l ≤ x < y ≤ r , l ≤ l c m ( x , y ) ≤ r \exist x,y\in\mathbb{Z}\ s.t.\ \ l\leq x<y\leq r,l\leq \mathrm{lcm}(x,y)\leq r x,yZ s.t.  lx<yr,llcm(x,y)r,若存在,输出任一组满足的 x , y x,y x,y;否则输出 − 1   − 1 -1\ -1 1 1.

思路

显然最优策略是取 l l l 2 l 2l 2l,则有解的充要条件是: r ≥ 2 l r\geq 2l r2l.

代码

void solve() {
	int l, r; cin >> l >> r;

	if (r < 2 * l) cout << "-1 -1" << endl;
	else cout << l << ' ' << 2 * l << endl;
}

int main() {
	CaseT  // 单测时注释掉该行
	solve();
}


1409C. Yet Another Array Restoration

原题指路:https://codeforces.com/problemset/problem/1409/C

题意

有一个包含 n n n个正整数的序列.已知其中 ∃ \exists 两元素 x , y   s . t .   x < y x,y\ s.t.\ x<y x,y s.t. x<y,且将该序列升序排列后是个等差数列.给定 x , y x,y x,y,构造一个 max ⁡ { a 1 , ⋯   , a n } \max\{a_1,\cdots,a_n\} max{a1,,an}最小的满足条件的序列.

t    ( 1 ≤ t ≤ 100 ) t\ \ (1\leq t\leq 100) t  (1t100)组测试数据.每组测试数据第一行输入三个整数 n , x , y    ( 2 ≤ n ≤ 50 , 1 ≤ x < y ≤ 50 ) n,x,y\ \ (2\leq n\leq 50,1\leq x<y\leq 50) n,x,y  (2n50,1x<y50).

对每组测试数据,输出一个长度为 n n n的满足条件的序列 a 1 , ⋯   , a n    ( 1 ≤ a i ≤ 1 e 9 ) a_1,\cdots,a_n\ \ (1\leq a_i\leq 1\mathrm{e}9) a1,,an  (1ai1e9).若有多组解,输出任一组.数据保证有解.

思路I

显然等差数列的公差 d d d y − x y-x yx的约数.添加元素 y , y − d , y − 2 d , ⋯ y,y-d,y-2d,\cdots y,yd,y2d,直至够 n n n个元素或下一个元素 < 1 <1 <1,检查 x x x是否在序列中,若在则该公差符合要求.若此时仍不足 n n n个元素,添加元素 y + d , y + 2 d , ⋯ y+d,y+2d,\cdots y+d,y+2d,直至够 n n n个元素,更新答案即可.时间复杂度 O ( n y − x ) O(n\sqrt{y-x}) O(nyx ).

代码I

void solve() {
	int n, x, y; cin >> n >> x >> y;

	vi ans;
	for (int d = 1; d <= y - x; d++) {
		if ((y - x) % d) continue;

		vi res;
		bool foundx = false;  // 记录x是否在序列中
		int need = n;  // 记录当前序列还差多少个元素
		int cur = y;  // 当前元素
		while (cur >= 1 && need) {
			res.push_back(cur);
			foundx |= cur == x;
			cur -= d;
			need--;
		}

		cur = y;
		while (need > 0) {  // 注意此处不能写while(need--),否则下面的!need不满足
			cur += d;
			res.push_back(cur);
			need--;
		}

		sort(all(res));
		if (!need && foundx) 
			if (ans.empty() || ans.back() > res.back()) ans = res;
	}

	for (auto i : ans) cout << i << ' ';
	cout << endl;
}

int main() {
	CaseT  // 单测时注释掉该行
	solve();
}

思路II

枚举公差 d d d,考虑直接求出首项.设首项 a 1 = y − k d ≥ 1 a_1=y-kd\geq 1 a1=ykd1,解得 k ≤ ⌊ y − 1 d ⌋ k\leq\left\lfloor\dfrac{y-1}{d}\right\rfloor kdy1.为保证 y y y在序列中,则 y y y至多是等差数列的第 n n n项,则 k ≤ n − 1 k\leq n-1 kn1.

代码II

void solve() {
	int n, x, y; cin >> n >> x >> y;

	int diff = y - x;
	for (int d = 1; d <= diff; d++) {
		if (diff % d) continue;
		if (diff / d > n - 1) continue;

		int k = min((y - 1) / d, n - 1);
		int a1 = y - k * d;
		for (int i = 0; i < n; i++) cout << a1 + i * d << " \n"[i == n - 1];
		break;
	}
}

int main() {
	CaseT  // 单测时注释掉该行
	solve();
}


1411B. Fair Numbers

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

题意

称一个正整数是fair的,如果它能被其所有非零数码整除.

t    ( 1 ≤ t ≤ 1000 ) t\ \ (1\leq t\leq 1000) t  (1t1000)组测试数据.每组测试数据输入一个整数 n    ( 1 ≤ n ≤ 1 e 18 ) n\ \ (1\leq n\leq 1\mathrm{e}18) n  (1n1e18).求 ≥ n \geq n n的最小的一个fair的数.

思路

称一个正整数是super fair的,如果它能被 1 ∼ 9 1\sim 9 19 9 9 9个数码整除.显然super fair的数是 2520 2520 2520的倍数.

显然答案不超过 ≥ n \geq n n的最小的super fair的数,暴力求即可.

代码

bool check(ll x) {
	string s = to_string(x);
	for (auto ch : s)
		if (ch != '0' && x % (ch & 15)) return false;
	return true;
}

void solve() {
	ll n; cin >> n;

	for (int i = 0; i < 2520; i++) {
		if (check(n)) {
			cout << n << endl;
			return;
		}
		n++;
	}
}

int main() {
	CaseT  // 单测时注释掉该行
	solve();
}


1455A. Strange Functions

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

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

对正整数 x x x,定义函数 f ( x ) f(x) f(x)表示将 x x x的十进制表示反转并去掉前导零得到的数字,如 f ( 321 ) = 123 , f ( 120 ) = 21 f(321)=123,f(120)=21 f(321)=123,f(120)=21.定义函数 g ( x ) = x f ( f ( x ) ) g(x)=\dfrac{x}{f(f(x))} g(x)=f(f(x))x.给定一个正整数 n n n,对 [ 1 , n ] [1,n] [1,n]中的任意整数 x x x,问 g ( x ) g(x) g(x)有多少种不同的取值.

t    ( 1 ≤ t ≤ 100 ) t\ \ (1\leq t\leq 100) t  (1t100)组测试数据.每组测试数据输入一个整数 n    ( 1 ≤ n < 1 e 100 ) n\ \ (1\leq n<1\mathrm{e}100) n  (1n<1e100).

思路

注意到 x = 1 x=1 x=1是最小的使得 g ( x ) = 1 g(x)=1 g(x)=1的数, x = 10 x=10 x=10是最小的使得 g ( x ) = 10 g(x)=10 g(x)=10的数, x = 100 x=100 x=100是最小的使得 g ( x ) = 100 g(x)=100 g(x)=100的数,故答案即 n n n的十进制表示(无前导零)的长度.

代码

void solve() {
	string s; cin >> s;
	cout << s.length() << endl;
}

int main() {
	CaseT  // 单测时注释掉该行
	solve();
}


1471A. Strange Partition

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

题意

给定一个长度为 n n n的序列 a 1 , ⋯   , a n a_1,\cdots,a_n a1,,an.现有如下操作:将两相邻元素替换为它们之和,注意每次操作后序列长度 − 1 -1 1.对给定的整数 x x x,定义序列的值为 ∑ i = 1 k ⌈ a i x ⌉ \displaystyle \sum_{i=1}^k \left\lceil\dfrac{a_i}{x}\right\rceil i=1kxai.问经过若干次(可能为零次)操作后给定序列的值最小和最大分别能取到多少.

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

思路

注意到 ⌈ a + b x ⌉ ≤ ⌈ a x ⌉ + ⌈ b x ⌉ \left\lceil\dfrac{a+b}{x}\right\rceil\leq \left\lceil\dfrac{a}{x}\right\rceil+\left\lceil\dfrac{b}{x}\right\rceil xa+bxa+xb,故不做任何操作时取得最大值,做 ( n − 1 ) (n-1) (n1)次操作时取得最小值.

代码

void solve() {
	int n, x; cin >> n >> x;

	vi a(n);
	ll ans1 = 0, ans2 = 0;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		ans1 += ceil((double)a[i] / x);
		ans2 += a[i];
	}
	ans2 = ceil((double)ans2 / x);
	cout << ans2 << ' ' << ans1 << endl;
}

int main() {
	CaseT  // 单测时注释掉该行
	solve();
}


1473B. String LCM

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

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

定义字符串 x x x与正整数 a a a的乘法 a ⋅ x a\cdot x ax表示将 x x x重复 a a a次.称字符串 a a a能被字符串 b b b整除,如果 ∃ x ∈ Z +   s . t .   b ⋅ x = a \exists x\in\mathbb{Z}^+\ s.t.\ b\cdot x=a xZ+ s.t. bx=a.定义字符串 s s s t t t的LCM为能整除 s s s t t t的最短的非空字符串,记作 l c m ( s , t ) \mathrm{lcm}(s,t) lcm(s,t).可以证明若 l c m ( s , t ) \mathrm{lcm}(s,t) lcm(s,t)存在,则它唯一.

t    ( 1 ≤ t ≤ 2000 ) t\ \ (1\leq t\leq 2000) t  (1t2000)组测试数据.每组测试数据输入两行分别表示只包含小写英文字母的字符串 s s s t    ( 1 ≤ ∣ s ∣ , ∣ t ∣ ≤ 20 ) t\ \ (1\leq |s|,|t|\leq 20) t  (1s,t20).

对每组测试数据,若 l c m ( s , t ) \mathrm{lcm}(s,t) lcm(s,t)存在,输出 l c m ( s , t ) \mathrm{lcm}(s,t) lcm(s,t);否则输出 − 1 -1 1.

思路

注意到若字符串 x x x是字符串 y y y的倍数,则 ∣ x ∣ |x| x ∣ y ∣ |y| y的倍数.显然若 l c m ( s , t ) \mathrm{lcm}(s,t) lcm(s,t)存在,则 ∣ l c m ( s , t ) ∣ = l c m ( ∣ s ∣ , ∣ t ∣ ) |\mathrm{lcm}(s,t)|=\mathrm{lcm}(|s|,|t|) lcm(s,t)=lcm(s,t),只需检查 l c m ( ∣ s ∣ , ∣ t ∣ ) ∣ s ∣ ⋅ s \dfrac{\mathrm{lcm(|s|,|t|)}}{|s|}\cdot s slcm(∣s∣,∣t∣)s l c m ( ∣ s ∣ , ∣ t ∣ ) ∣ t ∣ ⋅ t \dfrac{\mathrm{lcm(|s|,|t|)}}{|t|}\cdot t tlcm(∣s∣,∣t∣)t是否相等即可.

代码

string get(int a, string x) {
	string res;
	while (a--) res += x;
	return res;
}

void solve() {
	string s, t; cin >> s >> t;

	int n = s.length(), m = t.length();
	int d = gcd(n, m);
	cout << (get(m / d, s) == get(n / d, t) ? get(m / d, s) : "-1") << endl;
}

int main() {
	CaseT  // 单测时注释掉该行
	solve();
}


1474B. Different Divisors

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

题意

t    ( 1 ≤ t ≤ 3000 ) t\ \ (1\leq t\leq 3000) t  (1t3000)组测试数据.每组测试数据输入一个整数 d    ( 1 ≤ d ≤ 1 e 4 ) d\ \ (1\leq d\leq 1\mathrm{e}4) d  (1d1e4),求一个最小的正整数 a a a满足下列条件:① a a a至少有四个约数;② a a a的任意两约数之差 ≥ d \geq d d.

思路

为使得 a a a最小,显然 a a a有且只有 4 4 4个约数,此时 a a a有形式 a = p 3 a=p^3 a=p3 a = p q a=pq a=pq,其中 p , q ∈ p r i m e s p,q\in primes p,qprimes.

a = p 3 a=p^3 a=p3时, a a a有约数 1 , p , p 2 , p 3 1,p,p^2,p^3 1,p,p2,p3.

​ 注意到 p ≥ 2 p\geq 2 p2时,有 p 3 − p 2 > p 2 − p > p − 1 p^3-p^2>p^2-p>p-1 p3p2>p2p>p1,只需取最小的 p ≥ d + 1 p\geq d+1 pd+1即可.

a = p q a=pq a=pq时, a a a有约数 1 , p , q , p q 1,p,q,pq 1,p,q,pq.不妨设 p < q p<q p<q.

​ 取最小的 p ≥ d + 1 p\geq d+1 pd+1和最小的 q ≥ p + d q\geq p+d qp+d,此时 p q − q = q ( p − 1 ) ≥ q d > d pq-q=q(p-1)\geq qd>d pqq=q(p1)qd>d.

下面证明 ∄ p ′ , q ′ ∈ p r i m e s   s . t .   p ′ q ′ < p q \not\exist p',q'\in primes\ s.t.\ p'q'<pq p,qprimes s.t. pq<pq.

p p p是最小的 ≥ d + 1 \geq d+1 d+1的素数,则 p ′ ≥ p p'\geq p pp,同理 q ′ ≥ q q'\geq q qq.故 p ′ q ′ ≥ p q p'q'\geq pq pqpq.

时间复杂度 O ( g a p ⋅ p r i m e c h e c k ) O(gap\cdot primecheck) O(gapprimecheck),其中 g a p gap gap为相邻两素数间的距离,平均为 O ( log ⁡ a ) O(\log a) O(loga); p r i m e c h e c k primecheck primecheck为判断是否为素数的时间复杂度.

代码

void solve() {
	int d; cin >> d;

	vi primes;
	for (int i = d + 1;; i++) {  // 求≥d+1的最小素数p
		bool flag = true;  // 记录i是否为素数
		for (int j = 2; j * j <= i; j++) {
			if (i % j == 0) {
				flag = false;
				break;
			}
		}
		if (flag) {
			primes.push_back(i);
			break;
		}
	}

	for (int i = primes.back() + d;; i++) {  // 求≥p+d的最小素数q
		bool flag = true;  // 记录i是否为素数
		for (int j = 2; j * j <= i; j++) {
			if (i % j == 0) {
				flag = false;
				break;
			}
		}
		if (flag) {
			primes.push_back(i);
			break;
		}
	}

	cout << min((ll)primes[0] * primes[1], (ll)primes[0] * primes[0] * primes[0]) << endl;
}

int main() {
	CaseT  // 单测时注释掉该行
	solve();
}


1475A. Odd Divisor

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

题意 ( 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    ( 2 ≤ n ≤ 1 e 14 ) n\ \ (2\leq n\leq 1\mathrm{e}14) n  (2n1e14).若 n n n有奇约数,输出"YES";否则输出"NO".

思路

n n n素因数分解,则 n n n有奇约数的充要条件是: n n n有奇素因子.

注意到 2 2 2是唯一的偶素数,故 n n n无奇约数的充要条件是: n n n 2 2 2的幂次.

代码

void solve() {
	ll n; cin >> n;
	cout << (n & (n - 1) ? "YES" : "NO") << endl;
}

int main() {
	CaseT  // 单测时注释掉该行
	solve();
}


1485A. Add and Divide

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

题意

给定两正整数 a , b a,b a,b.现有如下两种操作:① a = ⌊ a b ⌋ a=\left\lfloor\dfrac{a}{b}\right\rfloor a=ba;② b = b + 1 b=b+1 b=b+1.求将 a a a变为 0 0 0的最小操作次数.

t    ( 1 ≤ t ≤ 100 ) t\ \ (1\leq t\leq 100) t  (1t100)组测试数据.每组测试数据输入两个整数 a , b    ( 1 ≤ a , b ≤ 1 e 9 ) a,b\ \ (1\leq a,b\leq 1\mathrm{e}9) a,b  (1a,b1e9).

思路

注意到 ⌊ a b + 1 ⌋ ≤ ⌊ a b ⌋ \left\lfloor\dfrac{a}{b+1}\right\rfloor\leq \left\lfloor\dfrac{a}{b}\right\rfloor b+1aba,则应先用操作②,即先将 b b b增大到某一值,再不断地用操作①直至 a = 0 a=0 a=0.注意特判 b < 2 b<2 b<2的情况.对 b ≥ 2 b\geq 2 b2的情况,至多需要 ⌊ log ⁡ 2 a ⌋ ≤ 29 \left\lfloor\log_2 a\right\rfloor\leq29 log2a29步即可使得 a = 0 a=0 a=0.

枚举用操作②的次数 i ∈ [ 0 , 30 ] i\in[0,30] i[0,30],对每个 i i i,求至少需用多少次操作①,更新答案即可.

时间复杂度 O ( log ⁡ 2 a ) O(\log^2 a) O(log2a).

代码

void solve() {
	ll A, B; cin >> A >> B;

	ll ans = A + 3;
	for (ll i = (B < 2 ? 2 - B : 0); i < ans; i++) {
		ll a = A, b = B + i;
		ll res = i;
		while (a) {
			a /= b;
			res++;
		}
		ans = min(ans, res);
	}
	cout << ans << endl;
}

int main() {
	CaseT  // 单测时注释掉该行
	solve();
}


1487B. Cat Cycle

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

题意

有编号 1 ∼ n 1\sim n 1n n n n个点围成一圈.初始时猫A在 n n n号点,猫B在 1 1 1号点.每个时刻两猫同时移动,其中猫A逆时针移动,猫B顺时针移动.若某时刻两猫移动到同一点处,则猫B逆时针多走一步到下一个点.求第 k k k个时刻时猫B所在的点的编号.

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

思路

①若 n n n为偶数,则不会出现两猫移动到同一点处的情况.

②若 n n n为奇数,则每 ⌊ n 2 ⌋ \left\lfloor\dfrac{n}{2}\right\rfloor 2n个时刻猫B会多走一步.因步数要对 n n n取模,不妨 k − − k-- k映射到下标从 0 0 0开始,最后 + 1 +1 +1即可.

代码

void solve() {
	int n, k; cin >> n >> k;
  cout << ((k - 1) + (n & 1) * ((k - 1) / (n / 2))) % n + 1 << endl;
}

int main() {
	CaseT  // 单测时注释掉该行
	solve();
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值