用编程解决一些入门的数学问题

斐波那切数列非递归形式

double feibonaqie(int n)//求斐波那切数列前n项和
{
	double a = 2, b = 1, sum = 0;
	for (int i = 1; i <= n; i++)
	{
		sum += a / b;
		int temp = a;
		a = a + b;
		b = temp;
	}
	return sum;
}

斐波那切数列递归形式

int feibonaqie1(int n)//求斐波那切数列某一项
{
	if (n == 1)
		return 0;
	else if (n == 2)
		return 1;
	else
		return feibonaqie1(n - 2) + feibonaqie1(n - 1);
}

进制转换问题

十进制转任意进制

void todany(int number, int n, char s[])//number为10进制数,n为要求进制,s为结果
{
	int i = 0, top = -1;
	while (number != 0)
	{
		i = number % n;
		if (i >= 10)//证明要求进制为16进制
			s[++top] = i - 10 + 'A';
		else
			s[++top] = i + '0';
		number /= n;
	}
	int k = top + 1;//转换后的是几位数
	for (int j = 0; j < k / 2; j++)//此时存的是倒序,应该逆置一下
	{
		char temp;
		temp = s[j];
		s[j] = s[k-1 - j];
		s[k-1 - j] = temp;
	}
	s[k] = '\0';//不要忘记
}

任意进制转十进制

int anytod(int n ,char s[])//n代表元素的类型,s为原数
{
	int sum=0, i = 0, t;
	while (s[i]!='\0')
	{
		if (s[i] >= 'A'&&s[i] <= 'F')
			t = s[i] - 'A' + 10;//针对ABCDEF需要特殊处理
		else
			t = s[i] - '0';//其余数字直接可以处理
		sum = sum * n + t;//重要步骤
		++i;
	}
	return sum;
}

约瑟夫环问题

约瑟夫环普通实现

#include<stdio.h>
int main()
{
    int a[30],n,i,j,m;
    scanf("%d%d",&n,&m);
    void loop(int *,int,int);
    for(i=0;i<n;i++)
    {
        a[i]=i+1;
    }
    printf("退出顺序为:\n");
    loop(a,n,m);
    return 0;
}
void loop(int a[],int n,int m)//核心代码
{
    int i=0,j=0,k=0,p;
    for(i;i<n&&j<n;i=(i+1)%n)
        {
            if(a[i]!=0)
            {
                k++;
            }
            if(k==m)
            {
                j++;
                printf("第%d个退出的是编号为%d的学生\n",j,a[i]);
                a[i]=0;
                k=0;
            }
        }
}

约瑟夫环链表实现

#include<stdio.h>
#include<stdlib.h>//malloc函数
typedef struct node
{
	int data;//结点的编号
	struct node *next;
}yue, *Yue;//Yue为链表类型,yue为结点类型
int main()
{
	int n, m;
	Yue p = NULL;//链表头指针,此时只是一个指针,还未为它分配存储空间(未初始化)
	printf("请输入人数和推出数:\n");
	scanf("%d%d", &n, &m);
	void chushihua(Yue&);//链表初始化函数声明,此处用引用可以实现改变p的指向(p的值)
	void yuesefu(Yue *, int, int);//约瑟夫环处理函数,此处采用二重指针,将p的地址传出函数,通过(*p)也可以改变p的指向,(**p)还可以改变p指向的变量的值
	void create(Yue &, int);//创建链表函数
	chushihua(p);
	create(p, n);
	yuesefu(&p, n, m);
	return 0;
}
void create(Yue &p, int n)
{
	yue *newnode = NULL, *q = p;//newnode为新结点,q是尾插法中用到的指针变量
	int i = 0, j = 0;
	for (i; i < n; i++)
	{
		newnode = (yue *)malloc(sizeof(yue));//新结点以尾插法插入链表
		newnode->data = i + 1;//第一个链表结点存编号为1的结点(数组实现的方法中下标为0的位置存着编号为1的顶点),以此类推
		newnode->next = q->next;
		q->next = newnode;
		q = newnode;
		newnode->next = p->next;//循环链表的操作:让最后一个结点的next域指向首元结点(不是头结点)
	}
}
void chushihua(Yue &p)
{
	//p = (Yue)malloc(sizeof(yue)*n);//为主函数中的指针变量p(头指针)初始化了一段长度为n个yue型结点长度大小的空间,无头结点,p指向这段存储空间第一个单元(首元结点)的地址
	p = (Yue)malloc(sizeof(yue));//p指向头结点
	p->next = p;//循环单链表
}
void yuesefu(Yue *p, int n, int m)//核心代码
{
	int now = 0, k = 0;//now用来记录已经退出了几个结点,k用来记录当前是第几个结点
	yue *pre, *q, *r;//pre用于删除链表结点时指向要被删除结点的前驱结点,q指向要被删除的结点(或者说当前结点)
	q = (*p)->next;//为了防止遍历过程中改变了原来头指针(在这里是*p)的指向(顶多在本函数中改变,只要不用return返回其实也无大碍),让q指向首元结点
	pre = q;//开始时pre指向头结点
	while (now < n)
	{
		while (q != NULL)
		{
			k++;
			if (k == m)//找到本次该退出的结点了
			{
				now++;
				printf("第%d次退出的结点编号为%d\n", now, q->data);
				pre->next = q->next;
				r = q;
				q = q->next;
				free(r);
				k = 0;
				break;
			}
			else
			{
				pre = q;
				q = q->next;
			}
		}
	}
}

马克思手稿问题

问题:30个人,有男人、女人、小孩,共吃饭用了50元,一个男人吃3元、女人吃2元、孩子吃1元,求出男人、女人和孩子各多少人?
穷举法解决

#include<stdio.h>
int main()
{
	for (int i = 1; i <= 16; i++)
	{
		for (int j = 1; j <= 25; j++)
		{
			for (int k = 1; k <= 50; k++)
			{
				if (i * 3 + j * 2 + k == 50&&i+j+k==30)
					printf("男人%d人,女人%d人,小孩%d人\n", i, j, k);
			}
		}
	}
}

方程法解决
思想:根据题意先把方程列出来,然后通过观察消元后的方程来施加一个约束条件,再用循环解决即可

#include<stdio.h>
int main()
{
	for (int i = 1; i <= 10; i++)
	{
		int j = 20 - 2 * i;
		int k = 30 - i - j;
		if(i*3+j*2+k==50&&j!=0&&k!=0)//不用再加i+j+k==30的条件了
			printf("男人%d人,女人%d人,小孩%d人\n", i, j, k);
	}
}

5元方案

问题:有1元、5角、1角硬币,输出组成5元的方案

#include<stdio.h>
int main()
{
	int i = 0, k, j, m;
	for (i = 0; i <= 5; i++)//注意条件的写法
	{
		for (j = 0; j <= (5 - i) * 2; j++)//注意条件的写法
		{
			for (k = 0; k <= (5 - i - j * 0.5)*10; k++)//注意条件的写法
			{
				if (i + j * 0.5 + k * 0.1 == 5)
					printf("1元%d枚,5角%d枚,1角%d枚\n", i, j, k);
			}
		}
	}
}

兵乓球对手问题

问题:a不和X比,c不和XZ比,求出他们彼此的对手

#include<stdio.h>
int main()
{
	char a, b, c;//代表甲队3人
	for (a = 'X'; a <= 'Z'; a++)
	{
		if (a != 'X')
		{
			for (b = 'X'; b <= 'Z'; b++)
			{
				for (c = 'X'; c <= 'Z'; c++)
				{
					if (a != b && a != c && b != c&&c!='X'&&c!='Z')
						printf("a→%c\nb→%c\nc→%c\n", a, b, c);
				}
			}
		}
	}
}

小球下落问题

#include<stdio.h>
int main()
{
	float sum = 100, sum1 = 50;
	int i = 2;
	while (i<=10)
	{
		sum = sum + sum1 * 2;
		i++;
		sum1 /= 2;
	}
	printf("%f   %f\n", sum, sum1);
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值