- 最小公约数和最大公倍数
#include<iostream>
#include<algorithm>
#include<string.h>
#include<cmath>
using namespace std;
long long G, L;
int main() {
int t;
cin >> t;
while (t--) {
cin >> G >> L;
if (L%G == 0)
cout << G << " " << L << '\n';
else
cout << -1 << '\n';
}
return 0;
}
–最小公倍数
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
int a, c;
int gcd(int a, int b){
return b == 0 ? a : gcd(b, a%b);
}
int main() {
int t;
cin >> t;
while (t--&&cin >> a >> c) {
if (c%a) cout << "NO SOLUTION\n";
else {
int b = c / a,r;
while ((r=gcd(a, b)) != 1)
a /= r, b = c / a;
cout << b << '\n';
}
}
return 0;
}
- 全加和
事先打表
#include<iostream>
#include<algorithm>
#include<string.h>
#define maxn 100
using namespace std;
long long d[maxn + 1][maxn + 1];
const int mod = 1000000;
int main() {
memset(d, 0, sizeof(d));
for (int i = 0; i <= maxn; i++) {
d[i][1] = 1;
}
for (int k = 2; k <= maxn; k++) {
for (int i = 0; i <= maxn; i++) {
for (int n = 0; n <= maxn; n++) if (n - i >= 0) {
d[n][k] =(d[n][k]+d[n - i][k - 1]) % mod;
}
}
}
int n, k;
while (cin >> n >> k&&n&&k) {
cout << d[n][k] << '\n';
}
return 0;
}
还有一种更快的方法,不过对于k个数的累加至n,我们用状态d(n,k)表示,
递推公式d(n,k)=sum{d(n,k-1)+d(n-1,k-1)} d(n,k-1) 表示与0搭配的顺序,d(n-1,k-1)表示与1搭配的顺序; 也可以考虑组合数的递推公式 不解;
#include<iostream>
#include<algorithm>
#define N 205
using namespace std;
typedef long long ll;
const int MOD = 1000000;
int n, k;
ll C[N][N];
void init()
{
memset(C, 0, sizeof(C));
C[0][0] = 1;
for (int i = 1; i < 200; i++)
{
C[i][0] = C[i][i] = 1;
for (int j = 1; j < i; j++)
C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
}
}
int main()
{
init();
while (~scanf("%d%d", &n, &k))
{
if (!n && !k)break;
int ans = C[n + k - 1][k - 1];
printf("%d\n", ans);
}
return 0;
}
- 幂和阶乘
#include<iostream>
#include<algorithm>
#include<string.h>
#define maxn 10000
#define maxm 5000
using namespace std;
int cal(int n, int p) {
int cur = 0;
for (int i = 2; i <= n; i++) {
int k = i;
while (k%p == 0) {
cur++;
k = k / p;
}
}
return cur;
}
int main() {
int n, m,t,kase=1;
cin >> t;
while (t--&&cin >> m >> n){
cout << "Case " << kase++ << ":\n";
int ans = maxm;
for (int j = 2; m > 1; j++) {
int pnum = 0;
while (m%j == 0) { pnum++, m /= j; }
if (pnum) {
int tt = cal(n, j) / pnum;
if (ans > tt) ans = tt;
}
}
if (ans)
cout << ans << '\n';
else
cout << "Impossible to divide\n";
}
return 0;
}
- LCM的个数
//int 型最大值为4294967296
#include<iostream>
#include<algorithm>
#include<string.h>
#include<cmath>
#define maxn 10000+10
using namespace std;
typedef long long ll;
int num[maxn];
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a%b);
}
int main() {
int n;
while (cin >> n && n) {
cout << n << " ";
if (n == 1) { cout << 1 << '\n'; continue; }
int tot = 0;
for (int i = 2; i < sqrt(n + 0.5); i++) {
if (n%i == 0)
num[tot++] = i, num[tot++] = n / i;
}
sort(num, num + tot);
tot = unique(num, num + tot) - num;
int coun = tot+2; //预处理有与自身有关的搭配
for (int i = 0; i < tot; i++)
for (int j = tot - 1; j >=i; j--)
if ((((ll)num[i] * num[j]) / gcd(num[j], num[i])) == n)
coun++;
cout << coun << '\n';
}
return 0;
}
- 超级幂
#include<iostream>
#include<algorithm>
#include<set>
#include<string.h>
#define maxn 64
using namespace std;
typedef unsigned long long ull;
const int p[18] = { 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61 };
ull lim = (1 << 64) - 1;
set<ull>s;
int main() {
int vis[maxn];
memset(vis, 0, sizeof(vis));
for (int i = 0; i < 18; i++) vis[p[i]] = 1;
for (int i = 2;; i++) {
ull x = lim;
int cnt = -1;
while (x) x /= i, cnt++;
if (cnt < 4) break;
ull b = i;
for (int j = 2; j <= cnt; j++) {
b = b * i;
if (!vis[j] && !s.count(b))
s.insert(b);
}
}
s.insert(1);
set<ull>::iterator it; //迭代器访问;
for (it = s.begin(); it != s.end(); it++)
cout << *it << '\n';
return 0;
}
- 排列之和
一个非常笨的方法 n>9以后就会非常慢
//运算量级太大;
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
typedef unsigned long long ull;
set<ull> s;
int num[13],vis[13],help[13];
int n;
ull tran() { //数组转化为数字;
ull ans = 0;
for (int i = 0; i < n; i++)
ans = ans * 10 + help[i];
return ans;
}
void dfs(int cur) {
if (cur == n) {
if (!s.count(tran())) s.insert(tran());
}
else {
for(int i=0;i<n;i++)
if (!vis[i]) {
help[cur] = num[i];
vis[i] = 1;
dfs(cur + 1);
vis[i] = 0;
}
}
}
int main() {
while (cin >> n && n) {
s.clear();
memset(vis, 0, sizeof(vis));
for (int i = 0; i <n; i++) cin >> num[i];
dfs(0);
set<ull>::iterator it;
ull ans = 0;
for (it = s.begin(); it != s.end(); it++)
ans += *it;
cout <<ans<< '\n';
}
return 0;
}
另辟奇径 网上搜的算法大佬
这个算法直到现在还是不理解啊,就这样,先记下来;
#include<iostream>
#include<algorithm>
#include <cmath>
using namespace std;
int n, x;
int vis[20];
long long fac[20];
long long one[13] = { 0, 1, 11, 111, 1111, 11111, 111111, 1111111, 11111111,111111111, 1111111111, 11111111111, 111111111111 };
//这个数组用的很巧,佩服啊QAQ
int main() {
fac[0] = 1;
for (int i = 1; i <= 12; i++)
fac[i] = fac[i - 1] * i;
while (cin >> n && n) {
memset(vis, 0, sizeof(vis));
int sum = 0;
long long ans;
for (int i = 0; i < n; i++) {
cin >> x;
vis[x]++;
sum += x;
}
ans = fac[n - 1] * sum;
for (int i = 0; i < 10; i++) {
ans /= fac[vis[i]];
}
cout << ans * one[n] << '\n';
}
return 0;
}
- 组队
一时间没想起来
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const ll mod = 1000000007;
ll pow(int n, int p) {
if (p == 1) { return n; }
else{
ll ans = pow(n, p / 2);
ans = (ans*ans) % mod;
if (p & 1) ans = (ans*n) % mod;
return ans;}
}
int main() {
int t, kase =1,n;
cin >> t;
while (t--) {
cin >> n;
cout << "Case #" << kase++ << ": ";
if (n == 1) cout << 1 << '\n';
else cout<< (n*pow(2, n-1)) % mod << '\n';
}
return 0;
}
- 回文数
转载大佬,也是不懂?
typedef long long ll;
ll p10[maxn], cnt[maxn], sum[maxn];
void inti() { //初始化p10和sum数组;
p10[0] = 1;
for (int i = 1; i < maxn; i++) p10[i] = p10[i - 1] * 10;
sum[0] = 0;
for (int i = 1; i < maxn; i++) {
cnt[i] = 9 * p10[(i - 1) / 2];
sum[i] = sum[i - 1] + cnt[i];
}
}
int ans[20], len;
void f(int i,int step) { //递归数组;
if (!step) return;
int j = len - 1 - i;
int p = (j - i - 2) / 2+1;
ans[i] = ans[j] = (step - 1) / p10[p];
if (p) f(i + 1, step - ans[i] * p10[p]);
}
int main() {
inti();
while(cin>>n&&n){
len = 1;
while (sum[len] < n) len++;
if (len == 1) { cout << n << '\n'; continue; }
if (len == 2) { n -= 9; cout << n << n << '\n'; continue; }
n -= sum[len-1];
int p = (len - 3) / 2 + 1;
ans[0] = ans[len - 1] = (n - 1) / p10[p] + 1;
n -= (ans[0] - 1)*p10[p];
if (n) f(1, n);
for (int i = 0; i < len; i++)
cout << ans[i];
cout << '\n';
}
return 0;
}
路漫漫其修远兮,吾将上下而求索
本文集锦了多种算法技巧,包括最小公倍数、全加和、幂和阶乘等复杂问题的解决方法,通过示例代码详细解析了算法背后的逻辑与实现细节。
2282

被折叠的 条评论
为什么被折叠?



