[Codeforces] number theory (R1200) Part.6

[Codeforces] number theory (R1200) Part.6

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

1245A. Good ol’ Numbers Coloring

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

题意

给定两整数 a , b a,b a,b.现对自然数集从小到大依次染色.设当前染到数字 i i i,规则如下:

①若 i = 0 i=0 i=0,将其染为白色.

②若 i ≥ a i\geq a ia i − a i-a ia是白色,则将 i i i染为白色.

③若 i ≥ b i\geq b ib i − b i-b ib是白色,则将 i i i染为白色.

④若 i i i还未被染色,将其染为黑色.

问最终被染成黑色的数的个数是否有限,若是则输出"Finite";否则输出"Infinite".

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

思路

注意到被染成白色的数有形式 a x + b y ax+by ax+by.

(1)若 gcd ⁡ ( a , b ) ≠ 1 \gcd(a,b)\neq 1 gcd(a,b)=1,则黑色的个数是无限的,因为能表示为 a x + b y ax+by ax+by的数是 gcd ⁡ ( a , b ) \gcd(a,b) gcd(a,b)的倍数,则相邻两白色的数之间至少有一个黑色的数.

(2)若 gcd ⁡ ( a , b ) = 1 \gcd(a,b)=1 gcd(a,b)=1,则黑色的个数是有限的.下面证明 > a b >ab >ab的数都会被染成白色.

​ 设 x > a b x>ab x>ab.考察集合 S = { x , x − a , x − 2 a , ⋯   , x − ( b − 1 ) a } S=\{x,x-a,x-2a,\cdots,x-(b-1)a\} S={x,xa,x2a,,x(b1)a}.

​ ①若 S S S中的元素都是 b b b的倍数,则 b ∣ ( x − a ) , b ∣ ( x − 2 a ) b\mid (x-a),b\mid (x-2a) b(xa),b(x2a),进而 b ∣ a b\mid a ba,又 b ∣ ( x − a ) b\mid (x-a) b(xa),则 b ∣ x b\mid x bx.

​ 这表明: ∀ x > a b \forall x>ab x>ab都是 b b b的倍数,则它们都会被染成白色.

​ ②若 S S S中的元素不全是 b b b的倍数,由抽屉原理: ∃ x − s a , x − t a ∈ S   s . t .   x − s a ≡ x − t a    ( m o d   b ) \exist x-sa,x-ta\in S\ s.t.\ x-sa\equiv x-ta\ \ (\mathrm{mod}\ b) xsa,xtaS s.t. xsaxta  (mod b).

​ 则 b ∣ ( x − s a ) − ( x − t a ) = a ( t − s ) b\mid (x-sa)-(x-ta)=a(t-s) b(xsa)(xta)=a(ts).不妨设 s < t s<t s<t.因 gcd ⁡ ( a , b ) = 1 \gcd(a,b)=1 gcd(a,b)=1,则 b ∣ ( t − s ) > 0 b\mid (t-s)>0 b(ts)>0.

​ 而 t − s ≤ t < b t-s\leq t<b tst<b,矛盾.故 S S S中的元素都是 b b b的倍数.

代码

void solve() {
	int a, b; cin >> a >> b;
	cout << (gcd(a, b) == 1 ? "Finite" : "Infinite") << endl;
}

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


1277B. Make Them Odd

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

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

给定一个长度为 n n n的序列 a 1 , ⋯   , a n a_1,\cdots,a_n a1,,an,每次可选择其中的一个偶数 x x x,将序列中所有等于 x x x的数除以 2 2 2.问至少经多少次操作后序列中只有奇数.

t    ( 1 ≤ t ≤ 1 e 4 ) t\ \ (1\leq t\leq 1\mathrm{e}4) t  (1t1e4)组测试数据.每组测试数据第一行输入一个整数 n    ( 1 ≤ n ≤ 2 e 5 ) n\ \ (1\leq n\leq 2\mathrm{e}5) n  (1n2e5).第二行输入 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之和不超过 2 e 5 2\mathrm{e}5 2e5.

思路

显然应先删除较大的偶数.用一个set维护当前序列中的偶数,每次取最大的元素扩展即可.

代码

void solve() {
	int n; cin >> n;
	set<int> s;
	while (n--) {
		int x; cin >> x;
		if (x % 2 == 0) s.insert(x);
	}

	int ans = 0;
	while (s.size()) {
		int tmp = *s.rbegin(); s.erase(tmp);
		if (tmp % 2 == 0) {
			ans++;
			s.insert(tmp / 2);
		}
	}
	cout << ans << endl;
}

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


1312A. Two Regular Polygons

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

题意

给定一个凸正 n n n边形 A A A,问是否能以 A A A的某些顶点为顶点,构造一个中心与 A A A重合的凸正 m    ( m < n ) m\ \ (m<n) m  (m<n)边形 B B B,若能则输出"YES";否则输出"NO".

t    ( 1 ≤ t ≤ 1 e 4 ) t\ \ (1\leq t\leq 1\mathrm{e}4) t  (1t1e4)组测试数据.每组测试数据输入两个整数 n , m    ( 3 ≤ m < n ≤ 100 ) n,m\ \ (3\leq m<n\leq 100) n,m  (3m<n100).

思路

若有解,显然应等间距地选择 A A A的顶点,故有解的充要条件是: m ∣ n m\mid n mn.

代码

void solve() {
	int n, m; cin >> n >> m;
	cout << (n % m ? "NO" : "YES") << endl;
}

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


1324A. Yet Another Tetris Problem

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

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

给定一个长度为 n n n的序列 a 1 , ⋯   , a n a_1,\cdots,a_n a1,,an.当 ∃ a i > 0 \exists a_i>0 ai>0时,有操作:①选择一个下标 i    ( 1 ≤ i ≤ n ) i\ \ (1\leq i\leq n) i  (1in),令 a i + = 2 a_i+=2 ai+=2;②若所有 a i > 0 a_i>0 ai>0,令所有 a i − = 1 a_i-=1 ai=1.问若干次操作后能否使得所有 a i    ( 1 ≤ i ≤ n ) a_i\ \ (1\leq i\leq n) ai  (1in)变为 0 0 0,若能则输出"YES";否则输出"NO".

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 ≤ 100 ) a_1,\cdots,a_n\ \ (1\leq a_i\leq 100) a1,,an  (1ai100).

思路

因操作①不改变 a i a_i ai的奇偶性,操作②同时改变所有 a i a_i ai的奇偶性,故有解的充要条件是:初始时各 a i a_i ai的奇偶性相同.

代码

void solve() {
	int n; cin >> n;
	vi a(n);
	for (auto& ai : a) {
		int x; cin >> x;
		ai = x & 1;
	}

	cout << (a == vi(n, a[0]) ? "YES" : "NO") << endl;
}

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


1325A. EhAb AnD gCd

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

题意

给定一个整数 x x x,求任一个整数对 ( a , b )   s . t .   gcd ⁡ ( a , b ) + l c m ( a , b ) = x (a,b)\ s.t.\ \gcd(a,b)+\mathrm{lcm}(a,b)=x (a,b) s.t. gcd(a,b)+lcm(a,b)=x.数据保证有解.

t    ( 1 ≤ t ≤ 100 ) t\ \ (1\leq t\leq 100) t  (1t100)组测试数据.每组测试数据输入一个整数 x    ( 2 ≤ x ≤ 1 e 9 ) x\ \ (2\leq x\leq 1\mathrm{e}9) x  (2x1e9).

思路

注意到 gcd ⁡ ( 1 , x − 1 ) + l c m ( 1 , x − 1 ) = 1 + ( x − 1 ) = x \gcd(1,x-1)+\mathrm{lcm}(1,x-1)=1+(x-1)=x gcd(1,x1)+lcm(1,x1)=1+(x1)=x.

代码

void solve() {
	int x; cin >> x;
	cout << 1 << ' ' << x - 1 << endl;
}

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


1326A. Bad Ugly Numbers

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

题意

给定一个整数 n n n,问是否存在满足下列条件的整数 s s s:① s > 0 s>0 s>0;② s s s的十进制表示有 n n n位;③ s s s的任一数码非零;④ s s s不被任一它的数码整除.若存在,输出任一符合条件的 s s s;否则输出 − 1 -1 1.

t    ( 1 ≤ t ≤ 400 ) t\ \ (1\leq t\leq 400) t  (1t400)组测试数据.每组测试数据第一行输入一个整数 n    ( 1 ≤ n ≤ 1 e 5 ) n\ \ (1\leq n\leq 1\mathrm{e}5) n  (1n1e5).数据保证所有测试样的 n n n之和不超过 1 e 5 1\mathrm{e}5 1e5.

思路

n = 1 n=1 n=1时,显然无解.

n ≥ 2 n\geq 2 n2时,易想到用数码 2 2 2 3 3 3构造一个奇数,这样可保证该数不能被 2 2 2整除.

​ 考虑如何保证该数不被 3 3 3整除,显然可构造数 23 ⋯ 3 ‾ \overline{23\cdots 3} 233.

代码

void solve() {
	int n; cin >> n;
	
	if (n == 1) cout << -1 << endl;
	else cout << 2 << string(n - 1, '3') << endl;
}

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


1364A. XXXXX

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

题意

给定一个长度为 n n n的序列 a 1 , ⋯   , a n a_1,\cdots,a_n a1,,an,问是否存在一个连续子列使得其中的元素之和不是 x x x的倍数,若存在,则输出最长连续子列的长度;否则输出 − 1 -1 1.

t    ( 1 ≤ t ≤ 5 ) t\ \ (1\leq t\leq 5) t  (1t5)组测试数据.每组测试数据第一行输入两个整数 n , x    ( 1 ≤ n ≤ 1 e 5 , 1 ≤ x ≤ 1 e 4 ) n,x\ \ (1\leq n\leq 1\mathrm{e}5,1\leq x\leq 1\mathrm{e}4) n,x  (1n1e5,1x1e4).第二行输入 n n n个整数 a 1 , ⋯   , a n    ( 0 ≤ a i ≤ 1 e 4 ) a_1,\cdots,a_n\ \ (0\leq a_i\leq 1\mathrm{e}4) a1,,an  (0ai1e4).

思路

显然最优解是某个前缀或某个后缀,检查每个前缀和后缀是否满足要求即可,用前缀和优化.

代码

void solve() {
	int n, x; cin >> n >> x;
	vi a(n + 1), pre(n + 1, 0);
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		pre[i] = pre[i - 1] + a[i];
	}

	int ans = -1;
	for (int l = 1; l <= n; l++) {
		if ((pre[n] - pre[l - 1]) % x) {
			ans = max(ans, n - l + 1);
			break;
		}
	}
	for (int r = n; r >= 1; r--) {
		if (pre[r] % x) {
			ans = max(ans, r);
			break;
		}
	}
	cout << ans << endl;
}

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


1370A. Maximum GCD

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

题意

[ 1 , n ] [1,n] [1,n]中选两个相异的整数使得它们的 gcd ⁡ \gcd gcd最大,输出最大的 gcd ⁡ \gcd gcd.

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

思路

gcd ⁡ \gcd gcd的最大值能取到 d d d,则至少 2 d ≤ n 2d\leq n 2dn,故 gcd ⁡ \gcd gcd的最大值即 ⌊ n 2 ⌋ \left\lfloor\dfrac{n}{2}\right\rfloor 2n.

代码

void solve() {
	int n; cin >> n;
	cout << n / 2 << endl;
}

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


1370B. GCD Compression

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

题意

给定一个长度为 2 n 2n 2n的序列 a 1 , ⋯   , a 2 n a_1,\cdots,a_{2n} a1,,a2n,现要将其压缩成一个长度为 ( n − 1 ) (n-1) (n1)的序列 b [ ] b[] b[],先删去 a [ ] a[] a[]中的任意两元素,再进行如下操作:选择 a [ ] a[] a[]中的两元素,将它们之和加入序列 b [ ] b[] b[],并将它们从 a [ ] a[] a[]中删除.构造任一个选择方案使得最终得到的序列 b [ ] b[] b[]中所有元素的 gcd ⁡ > 1 \gcd>1 gcd>1.

t    ( 1 ≤ t ≤ 10 ) t\ \ (1\leq t\leq 10) t  (1t10)组测试数据.每组测试数据第一行输入一个整数 n    ( 2 ≤ n ≤ 1000 ) n\ \ (2\leq n\leq 1000) n  (2n1000).第二行输入 2 n 2n 2n个整数 a 1 , ⋯   , a 2 n    ( 1 ≤ a i ≤ 1000 ) a_1,\cdots,a_{2n}\ \ (1\leq a_i\leq 1000) a1,,a2n  (1ai1000).

对每组测试数据输出 ( n − 1 ) (n-1) (n1)行,其中第 i i i行输入两个整数 i , j    ( 1 ≤ i , j ≤ 2 n , i ≠ j ) i,j\ \ (1\leq i,j\leq 2n,i\neq j) i,j  (1i,j2n,i=j),表示将 a i + a j a_i+a_j ai+aj加入序列 b [ ] b[] b[]并删除 a i a_i ai a j a_j aj.删去 a [ ] a[] a[]中的任意两元素无需输出.数据保证有解.

思路

考虑使得最终得到的序列 b [ ] b[] b[]中所有元素的 gcd ⁡ = 2 \gcd=2 gcd=2.

①若序列 a [ ] a[] a[]中有偶数个奇数,显然有解.

②若序列 a [ ] a[] a[]中有奇数个奇数,可初始时删除一个奇数和一个偶数,化为情况①.

代码

void solve() {
	int n; cin >> n;
	vi odd, even;
	for (int i = 1; i <= 2 * n; i++) {
		int a; cin >> a;
		if (a & 1) odd.push_back(i);
		else even.push_back(i);
	}

	vii ans;
	for (int i = 0; i + 1 < odd.size(); i += 2) ans.push_back({ odd[i],odd[i + 1] });
	for (int i = 0; i + 1 < even.size(); i += 2) ans.push_back({ even[i],even[i + 1] });

	for (int i = 0; i < n - 1; i++) cout << ans[i].first << ' ' << ans[i].second << endl;
}

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


1388A. Captain Flint and Crew Recruitment

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

题意

称一个正整数 x x x是nearly prime的,如果 ∃ 1 < p < q , p , q ∈ p r i m e s   s . t .   x = p q \exists 1<p<q,p,q\in primes\ s.t.\ x=pq ∃1<p<q,p,qprimes s.t. x=pq.给定一个正整数 n n n,问能否将其表示为 4 4 4个正整数之和,其中至少 3 3 3个数是nearly prime的.

t    ( 1 ≤ t ≤ 1000 ) t\ \ (1\leq t\leq 1000) t  (1t1000)组测试数据.每组测试数据输入一个整数 n    ( 1 ≤ n ≤ 2 e 5 ) n\ \ (1\leq n\leq 2\mathrm{e}5) n  (1n2e5).

对每组测试数据,若有解,输出"YES"并输出任一组解;否则输出"NO".

思路

最小的四个nearly prime的数是 6 , 10 , 14 , 15 6,10,14,15 6,10,14,15.

①若 n ≤ 30 = 6 + 10 + 14 n\leq 30=6+10+14 n30=6+10+14,则无解.

②若 n > 30 n>30 n>30,则 n = 6 + 10 + 14 + ( n − 30 ) n=6+10+14+(n-30) n=6+10+14+(n30).

​ 注意特判 n − 30 = 6 , 10 , 14 n-30=6,10,14 n30=6,10,14,即 n = 36 , 40 , 44 n=36,40,44 n=36,40,44的情况,此时可输出 6 , 10 , 15 , n − 31 6,10,15,n-31 6,10,15,n31.

代码

void solve() {
	int n; cin >> n;
	
	if (n <= 30) {
		cout << "NO" << endl;
		return;
	}

	cout << "YES" << endl;
	if (n == 36 || n == 40 || n == 44) cout << "6 10 15 " << n - 31 << endl;
	else cout << "6 10 14 " << n - 30 << endl;
}

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


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值