训练指南第二章-基础问题
训练指南第二章-基础问题 P170
![]() |
2 / 4 | Problem A | UVA 10943 | How do you add? |
![]() |
1 / 2 | Problem B | UVA 10780 | Again Prime? No Time. |
![]() |
1 / 1 | Problem C | UVA 10892 | LCM Cardinality |
![]() |
1 / 4 | Problem D | UVA 11752 | The Super Powers |
![]() |
1 / 3 | Problem E | UVA 11076 | Add Again |
![]() |
1 / 1 | Problem F | UVA 11609 | Teams |
![]() |
1 / 3 | Problem G | POJ 2402 | Palindrome Numbers(LA2889) |
![]() |
1 / 1 | Problem H | UVA 11489 | Integer Game |
![]() |
1 / 6 | Problem I | UVA 10791 | Minimum Sum LCM |
![]() |
1 / 1 | Problem J | UVA 11461 | Square Numbers |
![]() |
1 / 2 | Problem K | UVA 11388 | GCD LCM |
![]() |
1 / 2 | Problem L | UVA 11889 | Benefit |
![]() |
1 / 1 | Problem M | UVA 1319 | Maximum |
![]() |
1 / 1 | Problem N | UVA 1315 | Crazy tea party |
UVA 11388 GCD LCM
显然在合理的情况下,a=G,b=L
#include <bits/stdc++.h> int main() { int T; scanf ("%d", &T); while (T--) { int g, l; scanf ("%d%d", &g, &l); long long f = 1ll * g * l; if (l < g || l % g != 0) { puts ("-1"); } else { printf ("%d %d\n", g, l); } } return 0; }
UVA 11889 Benefit
解法一:分解质因数,因为,
,
,所以在ai小于最大值时bi为最大值,否则为0.
解法二:数学方法,tb=C/A,当g=GCD(A, tb) != 1,a /= g. tb *= .(不是很懂)
#include <bits/stdc++.h> void get_prime(int n, std::map<int, int> &mp) { int m = (int) sqrt (n + 0.5); for (int i=2; i<=m; ++i) { if (n % i == 0) { int cnt = 0; while (n % i == 0) { n /= i; mp[i]++; } } } if (n != 1) { mp[n]++; } } int _pow(int x, int n) { int ret = 1; while (n) { if (n & 1) { ret = ret * x; } n >>= 1; x = x * x; } return ret; } int solve(int a, int c) { std::map<int, int> mpa, mpc; get_prime (a, mpa); get_prime (c, mpc); int na = mpa.size (), nc = mpc.size (); if (na > nc || c % a != 0) { return -1; } else { int ret = 1; int m = (int) sqrt (c + 0.5); std::map<int, int>::iterator it; for (it=mpc.begin (); it!=mpc.end (); ++it) { if (!mpa.count (it->first) || mpa[it->first] < it->second) { ret *= _pow (it->first, it->second); } } return ret; } } int main() { int T; scanf ("%d", &T); while (T--) { int a, c; scanf ("%d%d", &a, &c); int ans = solve (a, c); if (ans != -1) { printf ("%d\n", ans); } else { puts ("NO SOLUTION"); } } return 0; }
#include <bits/stdc++.h> int GCD(int a, int b) { return b ? GCD (b, a % b) : a; } int solve(int a, int c) { if (a > c || c % a != 0) { return -1; } int tb = c / a; int g = GCD (a, tb); int mul = 1; while (g != 1) { mul *= g; a /= g; g = GCD (a, tb); } return tb * mul; } int main() { int T; scanf ("%d", &T); while (T--) { int a, c; scanf ("%d%d", &a, &c); int ans = solve (a, c); if (ans != -1) { printf ("%d\n", ans); } else { puts ("NO SOLUTION"); } } return 0; }
UVA 10943 How do you add?
这个用隔板法,
#include <bits/stdc++.h> int binom[205][205]; const int MOD = 1000000; void init_binom() { for (int i=1; i<=200; ++i) { binom[i][0] = binom[i][i] = 1; for (int j=1; j<i; ++j) { binom[i][j] = binom[i-1][j-1] + binom[i-1][j]; if (binom[i][j] >= MOD) { binom[i][j] -= MOD; } } } } int main() { init_binom (); int n, k; while (scanf ("%d%d", &n, &k) == 2) { if (!n && !k) { break; } printf ("%d\n", binom[n+k-1][k-1]); } return 0; }
UVA 10780 Again Prime? No Time.
分解质因数,取n!与m的某个质因数的个数商最小值。n!的某个质因数的个数=
#include <bits/stdc++.h> int main() { int T; scanf ("%d", &T); for (int cas=1; cas<=T; ++cas) { int m, n; scanf ("%d%d", &m, &n); int ans = 0x3f3f3f3f; int i = 2; while (m != 1) { int cnt = 0; while (m % i == 0) { cnt++; m /= i; } if (cnt) { int nn = n; int cnt2 = 0; while (nn) { cnt2 += nn / i; nn /= i; } ans = std::min (ans, cnt2 / cnt); } i++; } printf ("Case %d:\n", cas); if (ans) { printf ("%d\n", ans); } else { puts ("Impossible to divide"); } } return 0; }
UVA 10892 LCM Cardinality
分解质因数,暴力枚举~
#include <bits/stdc++.h> typedef long long ll; int GCD(int a, int b) { return b ? GCD (b, a % b) : a; } ll LCM(int a, int b) { return 1ll * a / GCD (a, b) * b; } int main() { int n; while (scanf ("%d", &n) == 1) { if (!n) { break; } std::vector<int> vec; int m = (int) sqrt (n + 0.5); for (int i=1; i<=m; ++i) { if (n % i == 0) { if (i != n / i) { vec.push_back (i); vec.push_back (n / i); } else { vec.push_back (i); } } } int ans = 1; //n n for (int i=0; i<vec.size (); ++i) { for (int j=i+1; j<vec.size (); ++j) { if (LCM (vec[i], vec[j]) == n) { ans++; } } } printf ("%d %d\n", n, ans); } return 0; }
UVA 11752 The Super Powers
只要指数不是素数才可以符合条件,技巧:取对数来求最大的指数
#include <bits/stdc++.h> typedef unsigned long long ull; int nprime[105]; bool is_prime(int n) { int m = (int) sqrt (n + 0.5); for (int i=2; i<=m; ++i) { if (n % i == 0) { return false; } } return true; } ull _pow(ull x, int n) { ull ret = 1; while (n) { if (n & 1) { ret = ret * x; } n >>= 1; x *= x; } return ret; } int main() { int tot = 0; for (int i=4; i<=64; ++i) { if (!is_prime (i)) { nprime[tot++] = i; } } std::map<ull, bool> mp; int bound = (1 << 16); for (int i=2; i<=bound; ++i) { double maxn = log (pow (2.0, 64.0)-1) / log (i); for (int j=0; j<tot; ++j) { int n = nprime[j]; if (n >= maxn) { break; } mp[_pow ((ull) i, n)] = true; } } mp[1] = true; std::map<ull, bool>::iterator it; for (it=mp.begin (); it!=mp.end (); ++it) { printf ("%llu\n", it->first); } return 0; }
UVA 11076 Add Again
设有重复元素的全排列数为x,,所以
,不考虑位置的话,总和为
,然后考虑进位累加的问题。
#include <bits/stdc++.h> typedef unsigned long long ull; int main() { int a[13], cnt[15]; ull f[13]; f[0] = f[1] = 1; for (int i=2; i<=12; ++i) { f[i] = f[i-1] * i; } int n; while (scanf ("%d", &n) == 1) { if (!n) { break; } memset (cnt, 0, sizeof (cnt)); int m = 0; for (int i=1; i<=n; ++i) { int x; scanf ("%d", &x); if (!cnt[x]) { a[m++] = x; } cnt[x]++; } ull sum = 0; for (int i=0; i<m; ++i) { ull div = f[cnt[a[i]]-1]; for (int j=0; j<m; ++j) { if (i != j) { div *= f[cnt[a[j]]]; } } sum += f[n-1] / div * a[i]; } //printf ("$%llu\n", sum); ull ans = 0; for (int i=1; i<=n; ++i) { ans += sum; sum *= 10; } printf ("%llu\n", ans); /* ull tmp = 0; std::vector<ull> ans; for (int i=1; i<=n; ++i) { ans.push_back ((sum + tmp) % 10); tmp = (sum + tmp) / 10; } if (tmp) { printf ("%llu", tmp); } for (int i=ans.size ()-1; i>=0; --i) { printf ("%llu", ans[i]); } puts (""); */ } return 0; }
UVA 11609 Teams
#include <bits/stdc++.h> const int MOD = 1e9 + 7; int pow_mod(int x, int n) { int ret = 1; while (n) { if (n & 1) { ret = 1ll * ret * x % MOD; } n >>= 1; x = 1ll * x * x % MOD; } return ret; } int main() { int T; scanf ("%d", &T); for (int cas=1; cas<=T; ++cas) { int n; scanf ("%d", &n); printf ("Case #%d: %d\n", cas, 1ll * pow_mod (2, n - 1) * n % MOD); } return 0; }
POJ 2402 Palindrome Numbers(LA2889)
按照回文串长度分组,找到是第n/num[i]+1组的第n%num[i]-1个位置,因为每组都从1000...0001开始,很容易找到规律。
#include <bits/stdc++.h> typedef long long ll; ll num[32]; ll tenp(int m) { ll ret = 1; while (m--) { ret *= 10; } return ret; } int main() { ll s = 9; num[1] = num[2] = s; for (int i=3; i<31; i+=2) { s *= 10; num[i] = num[i+1] = s; } int n; while (scanf ("%d", &n) == 1) { if (!n) { break; } int i; for (i=1; i<32 && n > num[i]; ++i) { n -= num[i]; } int l = i / 2 + (i & 1); ll x = tenp (l - 1) + n - 1; printf ("%I64d", x); if (i & 1) { x /= 10; } while (x) { printf ("%d", x % 10); x /= 10; } puts (""); } return 0; }
UVA 11489 Integer Game
除了第一次特判外,接下来只能取3,6,9(保证剩余数字是3的倍数),判断奇偶就可以了。
#include <bits/stdc++.h> const int N = 1e3 + 5; char str[N]; int cnt[10]; bool judge() { memset (cnt, 0, sizeof (cnt)); int sum = 0; for (int i=0; str[i]; ++i) { sum += str[i] - '0'; cnt[str[i]-'0']++; } bool flag = false; int t = sum % 3; for (int i=t; i<10; i+=3) { if (cnt[i]) { cnt[i]--; flag = true; break; } } if (!flag) { return false; } int tot = cnt[3] + cnt[6] + cnt[9]; return !(tot & 1); } int main() { int T; scanf ("%d", &T); for (int cas=1; cas<=T; ++cas) { scanf ("%s", str); printf ("Case %d: %c\n", cas, judge () ? 'S' : 'T'); } return 0; }
UVA 10791 Minimum Sum LCM
这题题目说的是set集合,不仅仅只是两个数字,结论是所有数字两两互质时最小,即分解质因数后,求
#include <bits/stdc++.h> long long solve(int n) { long long ret = 0; int cnt = 0; int m = (int) sqrt (n + 0.5); int nn = n; for (int i=2; i<=m; ++i) { if (n % i == 0) { cnt++; long long tmp = 1; while (n % i == 0) { n /= i; tmp *= i; } ret += tmp; } } if (!cnt || (cnt == 1 && n == 1)) { return 1ll + nn; } else { if (n != 1) { ret += n; } return ret; } } int main() { int n, cas = 0; while (scanf ("%d", &n) == 1) { if (!n) { break; } printf ("Case %d: %lld\n", ++cas, solve (n)); } return 0; }
UVA 11461 Square Numbers
前缀思想
#include <bits/stdc++.h> const int N = 1e5 + 5; int sum[N]; bool ok(int n) { int m = (int) sqrt (n); return m * m == n; } void init() { sum[0] = 0; for (int i=1; i<=100000; ++i) { sum[i] = sum[i-1]; if (ok (i)) { sum[i]++; } } } int main() { init (); int a, b; while (scanf ("%d%d", &a, &b) == 2) { if (!a && !b) { break; } printf ("%d\n", sum[b] - sum[a-1]); } return 0; }
UVA 1319 Maximum
都乘以。
,
。因为p是偶数,贪心思想一些数取-1,一些取a,还有一个在范围内。
#include <bits/stdc++.h> typedef long long ll; int main() { int m, p, a, b; while (scanf ("%d%d%d%d", &m, &p, &a, &b) == 4) { int sum = a * b; int x = 0, y = 0; for (int i=1; i<m; ++i) { if (sum >= a) { sum -= a; x++; } else { sum++; y++; } } double sa = sqrt (a * 1.0); double ans = y / pow (sa, p) + x * pow (sa, p); ans += pow (sum / sa, p); printf ("%d\n", (int) (ans + 0.5)); } return 0; }
UVA 1315 Crazy tea party
找规律,靠近1的往1挪,靠近n的往n挪。
#include <bits/stdc++.h> int main() { int T; scanf ("%d", &T); while (T--) { int n; scanf ("%d", &n); int m = (n - 1) / 2; int ans = (1 + m) * m; if (n & 1) { ans -= m; } printf ("%d\n", ans); } return 0; }