智力、数学题--

本文探讨了多种数学问题和编程算法的应用,包括找假币的最优化策略、数根计算、星际密码解密、因子个数统计、分解因数、猴子分桃问题、三角形验证、加法新解法以及饮料瓶兑换问题。通过这些实例展示了数学和编程在解决实际问题中的智慧和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有假币

平均分三份是最快的方法,两份进行称重(对比出三个的重量 ),后对最重的那份再次进行称重,直到称重的个数不足2个时则结束,获得假币 如果无法平均分3分则余数要么是1要么是2,3份分别是:n=n/3+1 n=n/3+1 n=n/3,这样是最快的时间可以分出,

#include <iostream>
using namespace std;

int  main()
{
	int n = 0;
	while (cin >> n)
	{
		if (n == 0)
		{
			return 0;
		}
		int count = 0;
		while (n > 1){
			count++;
			n = n / 3 + (n % 3 > 0);
		}
		cout << count << endl;
	}
	return 0;
}

数根

#include <iostream> 
#include <string>
int numRoot(int num)
{
	int nroot = 0; 
	while(num > 0) 
	{
		/*每次只获取个位数字---个位数+十位数*/
		nroot += num % 10; 得到最低位
		num /= 10;
	}
	while (nroot > 9) 
	{
		nroot = numRoot(nroot);
	}
	return nroot;
}1.由于数字太大,·需要使用string接收
int main() {
	std::string origin; 
	while(std::cin >> origin) 
	{
		int sum = 0; //先将每一位进行相加得到总和,防止数字过大 
		for (int i = 0; i < origin.length(); i++) 
		{ 
			sum += origin[i] - '0';
		}//对总和求树根
		std::cout << numRoot(sum) << std::endl;
	}
	return 0;
}/.直接对于接收回来的字符串进行求和
//求和的策略,·对每一个字符减去'0',·将得到的数字相加,字符串形式接收,然后减字符0,转为数字,

在这里插入图片描述

星际密码

#include <iostream>
#include <vector> 
std::vector<int> a = {1,1};
void data_init() 
{
	int i; 如果大于4位数,只取低4:斐波那契数列的值大于10000,在存储的时候 % 10000

	for(i=2;i<10005;i++)
	{ a.push_back((a[i-1]+a[i-2]) % 10000); }
}//左上角的数字: 斐波那契数列
int main()
{ 
	int n,t; data_init(); 
	while(std::cin >> n)
	{
		while(n--)
		{ std::cin >> t;
		printf("%04d",a[t]);
		}
		printf("\n");
	}return 0;
}

因子个数

从最小因子2到数字的最大因子数(数字的平方根)开始判断是否能够取余
可以则循环取余直到取余不为0,因子个数+1;否则使用下一个因子计算;
最终整除了各个因子数之后剩余的数字不为1则本身也是一个因子,因此因子数+1
如果因子是质数,就称因子为质因子
12 =2 * 6=2 * (2* 3 )
因子范围[2, sqrt[n]]
求得一个因子之后,我们还需要判断剩下的数字当中是否有该因子
例如︰8%2 = 4 …0此时4还可以拆解成为2*2,只能算一个质因子

#include <iostream>
#include<math.h>
using namespace std; 
int main() {
	int n,k,i; 
	while(cin >> n)
	{ k=0; 
	for(i = 2; i <= sqrt(n); i++) 
	{ 
		if ((n % i) == 0) 
		{
			while((n % i) == 0)
			{
				n=n/i;
			}
			k++; 
		}
	}
	if(n!=1) 
		k++; 
	cout<<k<<endl;
	}
	return 0; 
}

分解因数

90能被2整除,那就拿商继续除以2,除不尽就换3,一直到除到质数为止。基础代码框架类似判断质数,只是被判断的数字在过程中不断被除,最终循环结束的时候,那个被处理过的数字,就是最后一个质因数。

#include <iostream>
#include <cstdio> 
#include <vector>
using namespace std;
void factorization(int a, vector<int>& factors) {
	factors.clear();
	for (int i = 2; a > 1 && i * i <= a; i++) {
		while (a % i == 0) { 
			factors.push_back(i); a = a / i; 
		}
	}if (a > 1) { 
		// 处理素数的情况
		factors.push_back(a); 
	}
}int main() 
{ vector<int> factors;
int a; 
while (cin >> a)
{
	factorization(a, factors); 
	printf("%d = ", a); 
	for (vector<int>::const_iterator p = factors.begin(); p != factors.end(); ++p)
	{ 
		printf("%d", *p); 
		if (p != factors.end() - 1)
	{ printf(" * "); 
			}
	}
		printf("\n"); 
}
}

猴子分桃

在这里插入图片描述

#include <iostream>
#include <string> 
#include <math.h> 
int main() 
{
	int n; 
	while(std::cin >> n)
	{
		if (n == 0) break; 
		long total = pow(5, n) - 4; 
		long left = pow(4, n) + n - 4; 
		std::cout << total << " " << left << std::endl; 
	}
	return 0;
}

三角形

#include <iostream>
#include <string> 
#define ADD(x, y) ((x) + (y)) 
#define CMP(x, y) ((x) > (y)) 
int main() 
{
	double a, b, c;
	while (std::cin >> a >> b >> c) 
	{ //对两边进行求和与第三遍进行比较 
		if (CMP(ADD(a, b), c) && CMP(ADD(b, c), a) && CMP(ADD(a, c), b))
		{ std::cout << "Yes" << std::endl; 
		}
	else 
	{
		std::cout << "No" << std::endl; 
	}
	}return 0; 
}

不用加减乘除做加法

class Solution {
public: int Add(int num1, int num2)
{
	while (num2 != 0)
	{
		int sum = num1 ^ num2;//得到相加后不包含进位的数据 
		int carray = (num1 & num2) << 1; //得到两数相加的进位 
		num1 = sum;
		//两个结果相加,直到进位为0 
		num2 = carray;
	}
return num1;
}
};

在这里插入图片描述

1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以多少汽水

int Drink(int money) {
	int total = money;
	int empty = money;
	while (empty > 1){
		total = total + empty / 2;
		empty = empty/2 + empty % 2;
	}//喝完之后,最后一定有瓶子
			return		total; 
}
int main(){
		int money = 20;
		int c = Drink(money);
		printf("count = %d\n",c);
		}

HJ22 汽水瓶

#include<iostream>
#include<string>
using namespace std;
int calculateNum(int num) 
{
	//总兑换数
	int sum = 0;
	while (num > 1)
	{
		int result = num / 3;//可以兑换的个数
		int reminder = num % 3;//剩余不足三瓶的先保留
		sum = sum + result;
		//下一次可以兑换的空瓶
		num = result + reminder;
		if (num == 2)
		{
			sum++;
			break;
		}
	}
	return sum;
}
int main(){
	int number,res;
	while (cin >> number) {
		if (number = 0)
			break;
        res=calculateNum(number);
		cout <<  res<< endl;
	}
	return 0;
}

WY3 小易的升级之路

a=50,b1=50,b2=105,b3=200;
a=b1,最大公因子=50,a=100;a<b2,最大公因子=5,a=105;……最终是110=a,

#include<vector>
#include<iostream>
using namespace std;
int GCD(int a, int b) {
	int c; //展转相除法
	while (c = a % b)
	{
		a = b;
		b = c;
	}
	return b;
}
int main()
{
	int n, power;
	vector<int> num;
	while (cin >> n >> power)
	{
		num.resize(n);
		for (int i = 0; i < n; i++)
		{
			//输入敌人的防御值
			cin >> num[i];
		}
		for (int k = 0; k < n; k++)
		{
			if (num[k] < power)
			{
				power += num[k];
			}
			else
			{
				power += GCD(power, num[k]);
			}
		}
		cout << power << endl;
	}
	return 0;
}
  1. 如何根据(年、月、日)计算出这天是星期几
  2. 根据每月的1号是星期几,找到本月的第 n 个星期 X
  3. 根据 6月1日星期几,找到五月的最后一个星期一
#include <iostream> 
#include <cstdio>
using namespace std; 
bool isLeapYear(int y)
{ return y % 400 == 0 || (y % 100 != 0 && y % 4 == 0); }

int DAYS[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
// 求解 y,m,d 这一年过了多少天
int nDays(int y, int m, int d) 
{ int n = d;  
for (int i = 0; i < m - 1; i++) 
{ n += DAYS[i]; }
if (m > 2 && isLeapYear(y)) 
{ n++; }//闰年
return n; }// 传入 y,m,d 计算从基准日期,到带计算日期过了多少天。 
// 算出这个天数的 MOD 7 的同余数 
int diff(int y, int m, int d) 
{ return (y - 1) + (y - 1) / 4 - (y - 1) / 100 + (y - 1) / 400 + nDays(y, m, d); }
// 传入 y,m,d,计算周几 
int week(int y, int m, int d) 
{ int w = diff(y, m, d) % 7; 
if (w == 0) 
{ w = 7; }
return w; }// 已知当月1日是星期 w,计算第 n 个星期 e 是几号 
int m1(int w, int n, int e) 
{ return 1 + (n - 1) * 7 + (7 - w + e) % 7; }
// 已知6月1日(即5月32日)是星期w,计算5月的最后一个星期一 
int m2(int w) 
{ int d = (w == 1 ? 7 : w - 1);
return 32 - d; }

int main()
{ int y; 
while (cin >> y) 
{
	printf("%d-01-01\n", y);
	
	int w; 
	w = week(y, 1, 1);
	printf("%d-01-%02d\n", y, m1(w, 3, 1)); 
	w = week(y, 2, 1);
	printf("%d-02-%02d\n", y, m1(w, 3, 1)); 

	w = week(y, 6, 1); 
	printf("%d-05-%02d\n", y, m2(w)); 

	printf("%d-07-04\n", y);

	w = week(y, 9, 1); 
	printf("%d-09-%02d\n", y, m1(w, 1, 1));

	w = week(y, 11, 1); 
	printf("%d-11-%02d\n", y, m1(w, 4, 4)); 

	printf("%d-12-25\n\n", y);
}
}

在这里插入图片描述
在这里插入图片描述

和为S的连续正数序列

添加链接描述
//不考虑负数情况 ;[low ,high]之间就是一段连续递增的序列 。滑动窗口的两边,根据其窗口内的值的和来确定窗口的位置和大小 。闭区间解决 。差为1的一个序列,那么求和公式是(a0+an)*n/2。 //low和high不光代表位置,也代表对应的值 。//说明该序列区间中的数据和小于sum,应该扩大区间,以包含更多数据 :high++。

vector<vector<int> > FindContinuousSequence(int sum) {
	vector<vector<int> >result; 
int low = 1; int high = 2;
 while(low < high)
{ 
	int total = (low + high)*(high - low + 1)/2;	
	{ 
		vector<int> v; 
		for(int i = low; i <= high; i++)
		{ v.push_back(i); }
		result.push_back(v); 
//找到一组符合要求的序列之后,再找下一组序列只能从下一个数据low++开始
//而high会自动调节 
		low++; }
else if(total < sum){ 
high++; }
else{
low++; }
}
	return result; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值