欧拉计划 31~40

硬币求和
#include <bits/stdc++.h>
using namespace std;

int a[10] = {1, 2, 5, 10, 20, 50, 100, 200}, n = 8;
int f[209], m = 200;

int main() {
	f[0] = 1;
	for (int i = 0; i < n; i ++) {
		for (int j = a[i]; j <= m; j ++) {
			f[j] += f[j - a[i]];
		}
	}
	cout << f[m];

	return 0;
}
全数字的乘积
#include <bits/stdc++.h>
using namespace std;

int f[10000];	//f[k]==true表示k已经作为乘积出现过了 

bool fun(int a, int b) {
	int c = a * b;
	
	int h[10] = {1};	//出现0,返回false 
	while (a) {
		int t = a % 10;
		if (h[t]) return false;
		h[a % 10] = 1;
		a /= 10;
	}
	while (b) {
		int t = b % 10;
		if (h[t]) return false;
		h[b % 10] = 1;
		b /= 10;
	}
	
	while (c) {
		int t = c % 10;
		if (h[t]) return false;
		h[c % 10] = 1;
		c /= 10;
	}
	
	return true;
}

int main() {
	int ans = 0;
	for (int i = 1; i <= 9; i ++) {
		for (int j = 1000; j <= 9999; j ++) {
			if (fun(i, j)) {
				if (f[i * j] == 0) {
					ans += i * j;
					f[i * j] = 1;
				}
			}
		}
	}

	for (int i = 10; i <= 99; i ++) {
		for (int j = 100; j <= 999; j ++) {
			if (fun(i, j)) {
				if (f[i * j] == 0) {
					ans += i * j;
					f[i * j] = 1;
				}
			}
		}
	}
	
	cout << ans;

	return 0;
}


/*
1位 * 1位 = 7位 不成立

1位 * 2位 = 6位 不成立 

1位 * 3位 = 5位 不成立
2位 * 2位 = 5位 不成立

1位 * 4位 = 4位 成立
2位 * 3位 = 4位 成立

1位 * 5位 = 3位 不成立
2位 * 4位 = 3位 不成立
3位 * 3位 = 3位 不成立

*/
消去数字的分数
#include <bits/stdc++.h>
using namespace std;

int gcd(int x, int y) {
	return y == 0 ? x : gcd(y, x % y);
}

int main() {
	int a = 1, b = 1;							//最后的分子与分母 
	for (int i = 1; i < 10; i ++) {				//不考虑0,因为含有0的情况是平凡解
		for (int j = 1; j < 9; j ++) {
			for (int k = j + 1; k < 10; k ++) {	//j 一定小于 k 
				int u, d;						//分子,分母 
				
				u = 10 * j + i;
				d = 10 * i + k;
				if (u * k == d * j) {
					a *= u;
					b *= d; 
				}
				
				u = 10 * i + j;
				d = 10 * k + i;				
				if (u * k == d * j) {
					a *= u;
					b *= d;
				}
			}
		}
	}
	
	int t = gcd(a, b);
	cout << b / t; 

	return 0;
}

/*
(10*j + i) / (10*k + i) = j / k, 推出k = j, 舍
(10*i + j) / (10*i + k) = j / k, 推出k = j, 舍 

只考虑以下两种情况 

ji   j
-- = -
ik   k

ij   j
-- = -
ki   k
 
*/
各位数字的阶乘
#include <bits/stdc++.h>
using namespace std;

const int N = 3e6;
int f[10] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
int a[N + 9];

int main() {
	int sum = 0;
	for (int i = 1; i <= N; i ++) {
		a[i] = a[i / 10] + f[i % 10];
		if (a[i] == i) {
			sum += i;
		}
	}
	cout << sum - 1 - 2;

	return 0;
}

/*
6位数最大:362880 * 6 = 2177280 
7位数最大:362880 * 7 = 2540160
8位数最大:362880 * 8 = 2903040
*/
圆周素数
#include <bits/stdc++.h>
using namespace std;

const int N = 1e6;
bool a[N + 9];
int p[N], n;
int b[4] = {1, 3, 7, 9}, cnt;
int base[7] = {-1, 1, 10, 100, 1000, 10000, 100000};

void dfs(int x, int pos) {
	if (pos > 6) return;
	
	for (int i = 0; i < 4; i ++) {
		int num = x * 10 + b[i], t = num;
		
		bool flag = true;
		for (int j = 1; j <= pos; j ++) {
			if (a[t]) {
				flag = false;
				break;
			}
			t = t % 10 * base[pos] + t / 10;
		}
		if (flag) cnt ++;
		
		dfs(num, pos + 1);
	}
}

int main() {
	a[1] = true;
	for (int i = 2; i * i <= N; i ++) {
		if (!a[i]) {
			for (int j = i * i; j <= N; j += i) {
				a[j] = true;
			}
		}
	}
	
	dfs(0, 1);
	
	cout << cnt + 2;	//两个特殊数2和5 

	return 0;
}
双进制回文数
#include <bits/stdc++.h>
using namespace std;

int a[100000], n, ans;

int main() {
	for (int i = 1; i <= 9; i ++) {
		a[++ n] = i;
		a[++ n] = i * 11;
	}
	
	for (int i = 10; i < 100; i ++) {
		a[++ n] = i * 10 + i / 10;
		a[++ n] = i * 100 + i % 10 * 10 + i / 10;
	}

	for (int i = 100; i < 1000; i ++) {
		a[++ n] = i * 100 + i / 10 % 10 * 10 + i / 100;
		a[++ n] = i * 1000 + i % 10 * 100 + i / 10 % 10 * 10 + i / 100;
	}

	for (int i = 1; i <= n; i ++) {
		int t = a[i];
		int len = log2(t) + 1;
		
		bool flag = true;
		
		for (int j = 0, k = len - 1; j < k; j ++, k --) {
			if ((t >> j & 1) != (t >> k & 1)) {
				flag = false;
				break;
			}
		}
		
		if (flag) ans += t;
	}
	cout << ans;

	return 0;
}


/*
1位数:9
2位数:9
3位数:90
4位数:90
5位数:900
6位数:900 
*/
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值