数学专题(HDU19.3.15训练)

这是本人在半年前注册CSDN后原创的第一篇博客,算是在CSDN上的处女作吧,总结一些思路供以后翻阅。若这篇博文有幸被各位大佬过目,其中的很多不足还恳请各位多多指点。

在这篇blog中,我希望记录下对HDU数学专题训练部分题目知识点的一些思考。

一、Number Sequence

在这里插入图片描述
对于初学者,如果不仔细审题,可能会天真的开长度为100,000,000的数组再去遍历–>内存果断超限;亦或是想到使用数值交换的方法–>用时间超限替代了内存超限。。

那有什么idea能优化算法呢?

观察:f(1) = 1, f(2) = 1,

f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.长的是不是很像斐波那契数列?
(在输入循环内部,A,B都可以视为常量)

思考:既然f(n)是对7取余得到的,那么f(n-1)和f(n-2)一定和f(n)类似,属于区间[0,6],所以至多到7*7=49时出现循环,因此我们只需要找到循环的长度 ,问题便能迎刃而解。

代码:

#include<iostream>
using namespace std;
	int main()
	{
		int a[55],n,A,B,i;
		while(cin>>A>>B>>n,A!=0,B!=0,n!=0)	//输入循环
		{
			a[1]=1;	//对数组前两个元素初始化
			a[2]=1;
			for(i=3;i<=49;i++)	//最多只需遍历a[3]~a[49]即可找到循环节
			{
				a[i]=(A*a[i-1]+B*a[i-2])%7;
				if(a[i]==a[2]&&a[i-1]==a[1])	//找到循环位置,可以跳出for了
				break;
			}
			i-=2;	//i-2存回i,表示整个循环的长度
			if(n%i==0)	//若n能整除循环长度,输出a[n]
			n=i;
			else	//否则,n为整除i后的余值,即1到循环长度i中间的一个值
			n%=i;
			cout<<a[n]<<endl;	//输出a[n]即为结果
		}
	}

二、FatMouse’ Trade

在这里插入图片描述
思考:读完题不难看出本题主要考察贪心算法,顺带分治思想。我们可以使用结构体存放食物与比率变量–>接收数据–>按照“JavaBean/猫粮”进行降序排列–>每次换比最大–>最后的交换的javaBean最大。
代码:

#include<iostream>
#include<algorithm>
#include<iomanip>
using namespace std;

	struct trade
	{
	    int j; //JavaBean的数量
	    int f; //猫粮数量
	    double rate; //一份猫粮能换到JavaBean的数量
	}p[3005];
	bool cmp(trade a,trade b)
	{
	    return a.rate > b.rate;//sort函数降序规则
	}
	int main()
	{
		int M,N;//M磅猫粮,N个仓库房间
		while(cin>>M>>N,M!=-1,N!=-1)//样例输入循环
		{
			for(int i=0;i<N;i++) //在第i个仓库房间,猫粮换食物
			{
				cin>>p[i].j>>p[i].f;
				p[i].rate=(double)p[i].j/p[i].f; //兑换比率
			}
			sort(p,p+N,cmp);//降序排序
			double sum=0;//定义老鼠吃到的总食物数
	        for(int i=0;i<N;i++)
	        {
	            if(M>p[i].f)
	            { //如果剩下的猫粮大于换取某个仓库房间所需猫粮,则把仓库里面的全部换走
	                sum+=p[i].j;
	                M-=p[i].f;
	            }
	            else //最后剩下的猫粮换不了某个仓库房间里面的全部,则换取部分即可,并且结束了交易
	            {
	                sum+=p[i].rate*M;
	                M=0;
	                break;
	            }
	        }
	        printf("%.3lf\n",sum);//不太清楚为什么使用cout输出会提示答案错误。
			//cout<<fixed<<setprecision(3)<<sum<<endl;
		}
	}

三、Fibonacci Again

在这里插入图片描述
观察:本题需要重点解决两个问题:

  1. 这个“斐波那契数列”可以直接遍历求解吗?–>显然不可以–>如何解决?
  2. 题目中n的最大值很大,如何建立数组?

思考:题目只要求判断F(n)是否能够被3整除,能否借助此条件简化计算?

代码:

#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
#define N 1000000
int a[N];
	int main()
	{
		int n;
		memset(a,0,sizeof(a));//memset函数申请内存建议数组暂且理解为动态建立数组吧
		a[0]=7%3;a[1]=11%3;
		while(cin>>n)
		{
			for(int i=2;i<=n;i++)
			{
				a[i]=(a[i-1]%3+a[i-2]%3)%3;//通过模操作限制了数值大小
			}
			if(a[n]==0)
			{
				printf("yes\n");
			}
			else
			{
				printf("no\n");
			}
		}

	}
	

四、素数回文

在这里插入图片描述
评价:本题主要考察判断素数及回文数的能力,应该属于签到题。
代码:

#include <iostream>
#include <cstdio>
using namespace std;
int a[10000001];

	int sushu(int n)//素数函数
	{
	    if(n==2)return 1;
	    for(int i=2; i*i<=n; i++)
	        if(n%i==0)
	            return 0;
	    return 1;
	}
	int huiwen(int n)//回文函数
	{
	    int m=0,t=n;
	    while(t)
	    {
	        m=m*10+t%10;
	        t/=10;
	    }
	    if(m==n)
	        return 1;
	    return 0;
	}

	int main()
	{
	    int n,m;
	    while(cin>>n>>m)
	    {
	        for(int i=n;i<=m&&i<=9989899;i++)
	            if (huiwen(i)&&sushu(i))
	                printf("%d\n",i);
	        printf("\n");
	    }
	}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值