[Codeforces] number theory (R1200) Part.4
题单:https://codeforces.com/problemset/page/6?tags=number%20theory,0-1200
787A. The Monster
原题指路:https://codeforces.com/problemset/problem/787/A
题意
给定四个整数a,b,c,d (1≤a,b,c,d≤100)a,b,c,d\ \ (1\leq a,b,c,d\leq 100)a,b,c,d (1≤a,b,c,d≤100),求序列{b,b+a,b+2a,⋯ }\{b,b+a,b+2a,\cdots\}{b,b+a,b+2a,⋯}和{d,d+c,d+2c,⋯ }\{d,d+c,d+2c,\cdots\}{d,d+c,d+2c,⋯}中最早出现的相等项,若不存在,输出−1-1−1.
思路
加ccc次aaa的结果与加aaa次ccc的结果相同,故有解ax+b=cy+dax+b=cy+dax+b=cy+d时,x,y≤max{a,b,c,d}≤100x,y\leq \max\{a,b,c,d\}\leq 100x,y≤max{a,b,c,d}≤100,枚举即可.
代码
void solve() {
int a, b, c, d; cin >> a >> b >> c >> d;
for (int i = 0; i <= 100; i++) {
int cur = b + i * a;
if (cur - d >= 0 && (cur - d) % c == 0) {
cout << cur;
return;
}
}
cout << -1;
}
int main() {
solve();
}
797A. k-Factorization
原题指路:https://codeforces.com/problemset/problem/797/A
题意
给定一个整数n (2≤n≤1e5)n\ \ (2\leq n\leq 1\mathrm{e}5)n (2≤n≤1e5),将其分解为k (1≤k≤20)k\ \ (1\leq k\leq 20)k (1≤k≤20)个>1>1>1的整数之积.若有解,输出任一组解;否则输出−1-1−1.
思路
将nnn素因数分解,结果存在一个vector中.
①若vector的元素个数<k<k<k,无解.
②若vector的元素个数=k=k=k,输出集合中的元素即可.
③若vector的元素个数>k>k>k,合并若干个因数直至集合的元素个数=k=k=k.
代码
void solve() {
int n, k; cin >> n >> k;
vi ans;
for (int i = 2; i <= n / i; i++) {
if (n % i == 0) {
while (n % i == 0) {
ans.push_back(i);
n /= i;
}
}
}
if (n > 1) ans.push_back(n);
if (ans.size() < k) cout << -1;
else if (ans.size() == k)
for (auto i : ans) cout << i << ' ';
else {
while (ans.size() > k) {
int a = ans.back(); ans.pop_back();
int b = ans.back(); ans.pop_back();
ans.push_back(a * b);
}
for (auto i : ans) cout << i << ' ';
}
}
int main() {
solve();
}
817A. Treasure Hunt
原题指路:https://codeforces.com/problemset/problem/817/A
题意
给定两整数x,yx,yx,y.现有四种操作:①(a,b)→(a+x,b+y)(a,b)\rightarrow(a+x,b+y)(a,b)→(a+x,b+y);②(a,b)→(a+x,b−y)(a,b)\rightarrow(a+x,b-y)(a,b)→(a+x,b−y);③(a,b)→(a−x,b+y)(a,b)\rightarrow(a-x,b+y)(a,b)→(a−x,b+y);④(a,b)→(a−x,b−y)(a,b)\rightarrow(a-x,b-y)(a,b)→(a−x,b−y).问是否能从点(x1,y1)(x_1,y_1)(x1,y1)经过若干次操作到达点(x2,y2)(x_2,y_2)(x2,y2),若能则输出"YES";否则输出"NO".
第一行输入四个整数x1,y1,x2,y2 (−1e5≤x1,y1,x2,y2≤1e5)x_1,y_1,x_2,y_2\ \ (-1\mathrm{e}5\leq x_1,y_1,x_2,y_2\leq 1\mathrm{e}5)x1,y1,x2,y2 (−1e5≤x1,y1,x2,y2≤1e5).第二行输入两个整数x,y (1≤x,y≤1e5)x,y\ \ (1\leq x,y\leq 1\mathrm{e}5)x,y (1≤x,y≤1e5).
思路
显然有解的必要条件是:∣x1−x2∣ mod x=0,∣y1−y2∣ mod y=0|x_1-x_2|\ \mathrm{mod}\ x=0,|y_1-y_2|\ \mathrm{mod}\ y=0∣x1−x2∣ mod x=0,∣y1−y2∣ mod y=0.
下面考察能否达到(x1,y1)=(x2,y2)(x_1,y_1)=(x_2,y_2)(x1,y1)=(x2,y2).设cntx=∣x1−x2∣x,cnty=∣y1−y2∣ycnt_x=\dfrac{|x_1-x_2|}{x},cnt_y=\dfrac{|y_1-y_2|}{y}cntx=x∣x1−x2∣,cnty=y∣y1−y2∣.注意到每个操作都会同时使得cntxcnt_xcntx和cnty±1cnt_y\pm 1cnty±1,故有解的充要条件是:cntxcnt_xcntx与cntycnt_ycnty的奇偶性相同.
代码
void solve() {
int x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2;
int x, y; cin >> x >> y;
if ((x1 - x2) % x || (y1 - y2) % y) cout << "NO";
else {
int cntx = abs(x1 - x2) / x, cnty = abs(y1 - y2) / y;
cout << ((cntx & 1) == (cnty & 1) ? "YES" : "NO");
}
}
int main() {
solve();
}
822A. I’m bored with life
原题指路:https://codeforces.com/problemset/problem/822/A
题意
给定两整数a,b (1≤a,b≤1e9,min{a,b}≤12)a,b\ \ (1\leq a,b\leq 1\mathrm{e}9,\min\{a,b\}\leq 12)a,b (1≤a,b≤1e9,min{a,b}≤12),求gcd(a!,b!)\gcd(a!,b!)gcd(a!,b!).
思路
显然gcd(a!,b!)=min{a,b}!\gcd(a!,b!)=\min\{a,b\}!gcd(a!,b!)=min{a,b}!.
答案最大为12!≈4e812!\approx 4\mathrm{e}812!≈4e8,不会爆int.
代码
void solve() {
int a, b; cin >> a >> b;
int ans = 1;
for (int i = 2; i <= min(a, b); i++) ans *= i;
cout << ans;
}
int main() {
solve();
}
858A. k-rounding
原题指路:https://codeforces.com/problemset/problem/858/A
题意
对一个整数nnn,定义它的k−k-k−rounding为十进制下以至少kkk个零结尾的最小的nnn的倍数.给定两整数n,k (1≤n≤1e9,0≤k≤8)n,k\ \ (1\leq n\leq 1\mathrm{e}9,0\leq k\leq 8)n,k (1≤n≤1e9,0≤k≤8),求nnn的k−k-k−rounding.
思路
ans=lcm(n,10k)ans=\mathrm{lcm}(n,10^k)ans=lcm(n,10k).
代码
void solve() {
int n, k; cin >> n >> k;
cout << lcm(n, (int)pow(10, k));
}
int main() {
solve();
}
898B. Proper Nutrition
原题指路:https://codeforces.com/problemset/problem/898/B
题意
给定三个整数n,a,b (1≤a,b,n≤1e7)n,a,b\ \ (1\leq a,b,n\leq 1\mathrm{e}7)n,a,b (1≤a,b,n≤1e7),求一个非负整数对(x,y) s.t. ax+by=n(x,y)\ s.t.\ ax+by=n(x,y) s.t. ax+by=n.若有解,输出"YES",并输出任一组解;否则输出"NO".
思路
暴力即可.
代码
void solve() {
int n, a, b; cin >> n >> a >> b;
for (int x = 0; x <= 1e7; x++) {
ll cur = (ll)n - (ll)x * a;
if (cur >= 0 && cur % b == 0) {
cout << "YES" << endl;
cout << x << ' ' << cur / b;
return;
}
}
cout << "NO";
}
int main() {
solve();
}
919B. Perfect Number
原题指路:https://codeforces.com/problemset/problem/919/B
题意 (2 s2\ \mathrm{s}2 s)
求第k (1≤k≤1e4)k\ \ (1\leq k\leq 1\mathrm{e}4)k (1≤k≤1e4)小的数位之和为101010的正整数.
思路
由101010的分拆数乘上全排列,中间还可以插000,可估计出前1e41\mathrm{e}41e4个满足条件的数不会很大,暴力求即可.
代码
void solve() {
int k; cin >> k;
function<bool(int)> get = [](int x)->bool {
string s = to_string(x);
int res = 0;
for (auto ch : s) res += ch & 15;
return res == 10;
};
int ans = 0;
while (k) k -= get(++ans);
cout << ans;
}
int main() {
solve();
}
946B. Weird Subtraction Process
原题指路:https://codeforces.com/problemset/problem/946/B
题意
给定两数a,b (1≤a,b≤1e18)a,b\ \ (1\leq a,b\leq 1\mathrm{e}18)a,b (1≤a,b≤1e18),现有如下三步操作:
①若a=b=0a=b=0a=b=0,操作结束,否则执行步骤②.
②若a≥2ba\geq 2ba≥2b,令a=a−2ba=a-2ba=a−2b,执行步骤①;否则执行步骤③.
③若b≥2ab\geq 2ab≥2a,令b=b−2ab=b-2ab=b−2a,执行步骤①;否则操作结束.
求操作结束后的a,ba,ba,b.
思路
将若干次减法合并为一次取模,模拟该过程即可.
代码
void solve() {
ll a, b; cin >> a >> b;
while (a && b) {
a %= 2 * b;
if (!a || b < 2 * a) break;
else b %= 2 * a;
}
cout << a << ' ' << b;
}
int main() {
solve();
}
1033B. Square Difference
原题指路:https://codeforces.com/problemset/problem/1033/B
题意
在边长为aaa的正方形的左上角切除一个边长为b (b<a)b\ \ (b<a)b (b<a)的正方形,问剩下的L型的面积是否是素数.
有t (1≤t≤5)t\ \ (1\leq t\leq 5)t (1≤t≤5)组测试数据.每组测试数据输入两个整数a,b (1≤b<a≤1e11)a,b\ \ (1\leq b<a\leq 1\mathrm{e}11)a,b (1≤b<a≤1e11).
思路
注意到a2−b2=(a−b)(a+b)a^2-b^2=(a-b)(a+b)a2−b2=(a−b)(a+b),显然L的面积是素数的充要条件是:a−b=1,a+b∈primesa-b=1,a+b\in primesa−b=1,a+b∈primes.
因a+b≤2e11a+b\leq 2\mathrm{e}11a+b≤2e11,用试除法判定素数即可.注意此处用Miller-Rabin算法中间会爆ll.
代码
bool check(ll x) {
for (int i = 2; i <= sqrt(x); i++)
if (x % i == 0) return false;
return true;
}
void solve() {
ll a, b; cin >> a >> b;
cout << (a - b == 1 && check(a + b) ? "YES" : "NO") << endl;
}
int main() {
CaseT // 单测时注释掉该行
solve();
}
1051B. Relatively Prime Pairs
原题指路:https://codeforces.com/problemset/problem/1051/B
题意 (2 s2\ \mathrm{s}2 s)
给定两个整数l,r (1≤l≤r≤1e18,r−l+1≤3e5,r−l是偶数)l,r\ \ (1\leq l\leq r\leq 1\mathrm{e}18,r-l+1\leq 3\mathrm{e}5,r-l是偶数)l,r (1≤l≤r≤1e18,r−l+1≤3e5,r−l是偶数).若能将[l,r][l,r][l,r]中的所有整数分为r−l+12\dfrac{r-l+1}{2}2r−l+1个数对,使得每个数在且仅在一个数对中,且每个数对的gcd=1\gcd=1gcd=1,输出"YES"并输出一个合法方案;否则输出"NO".
思路
注意到相邻两数的gcd=1\gcd=1gcd=1,依次输出即可.
代码
void solve() {
ll l, r; cin >> l >> r;
cout << "YES" << endl;
for (ll i = l; i <= r; i += 2) cout << i << ' ' << i + 1 << endl;
}
int main() {
solve();
}