算法提高题(流汗黄豆只能说有些可以算提高)

1.回文串

题目大意:输入k(k<=10^9)让你输出第k大的回文串

思路:有一个规律:一位数和两位数的回文串数量一样,三位数和四位数的回文串数量一样…那么我们直接枚举回文串的一半,用一个bool类型的变量来存储当前的答案是单数还是双数(是要先判断第k大的回文串的范围的再来枚举求得)
2.判断一个数n是否是质数

优化方法:只需要看<=sqrt(n)范围看是否能整除(原理是一个数可以分为两个数相乘,其中一个数小于sqrt(n),另一个数就一定大于sqrt(n),这两个数如果其中一个被整除,那这个数就不是质数了。

3.最大体积

题目大意:有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数)。

要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

看数据范围只要搜索加上部分剪枝即可,代码如下:
//得到答案不超过v所能得到的最大值
#include<iostream>
using namespace std;
int a[35];
int v,n;
int ans;
void dfs(int i,int m)//当前编号,当前容量 
{
	if(m>v)
	{
		return;
	}
	else if(i==n)
	{
		ans=max(ans,m);
		return;
	 } 
	else 
	{
		ans=max(ans,m);
		dfs(i+1,m+a[i+1]);//装 
		dfs(i+1,m);//不装 
	}
	
}
int main()
{
	ios::sync_with_stdio(false);
	cin>>v;
	cin>>n;
	for(int i=1;i<=n;i++)
	cin>>a[i];
	dfs(0,0);
	cout<<(v-ans)<<endl;
	return 0;
 }   
4.多源最短路径(Floyd)
5.一元三次方程求解

…有bug二分加枚举50分(待改)
代码如下:

//每一个长度为1的区间内最多只有一个解
#include<iostream>
#include<cstdio> 
#include<set>
using namespace std;
double ans1,ans2;
set<double>v;
double a,b,c,d;
double Value(double k)
	{
		return a*k*k*k+b*k*k+c*k+d;
	}
int main()
{
	cin>>a>>b>>c>>d;
	for(double i=-100.0;i<=99.0;i++)
	{
		double ans1=Value(i);
		double ans2=Value(i+1);    
		//判断异号 
		if(ans1*ans2<=0)
		{          
			double l=i;    
			double r=i+1;
			while(l<=r) 
			{
				double ans1=Value(l);
				//cout<<ans1<<endl;
				if(ans1==0)
				{
					v.insert(l);
					break;
				}
		        double ans2=Value(r);
		        //cout<<ans2<<endl;
		        if(ans2==0)
				{
					v.insert(r);
					break;
				}
				double mid=(l+r)/2;
				double ans3=Value(mid);
				cout<<ans3<<endl;
				if(ans3==0)
				{
					v.insert(mid);
					break;
				}
				else 
				{
					if(ans1/ans1!=ans3/ans3)
					r=mid-0.0001;
					else 
					{
						l=mid+0.0001;
					}
				}
			}
		}
	}
	for(set<double>::iterator it=v.begin();it!=v.end();it++)
	{
		printf("%.2lf ",*it);
	}
	return 0;
 } 
6.十六进制转八进制

很简单的一道题,我甚至不想写题解了。

7.高精度计算

题目:

用高精度计算出S=1!+2!+3!+…+n!(n≤50)
  其中“!”表示阶乘,例如:5!=54321。
  输入正整数N,输出计算结果S。
输入格式
  输入包含一个整数N(N<=50)
输出格式
  输出为一个整数,为计算结果S。

思路:涉及到高精度加法和高精度乘法,算法并不难 主要考察高精度加法和高精度乘法,AC代码如下:
//高精度乘法
//答案出现了: 
#include<iostream>
#include<cstring>
#include<sstream> 
using namespace std;
stringstream sm;
int a[100005];
int b[100005];
int c[100005];
string Add(string s1,string s2)
{
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	memset(c,0,sizeof(c));
	int len1=s1.size();
	int len2=s2.size();
	int len=max(len1,len2);
	for(int i=1;i<=len1;i++)
	a[i]=s1[len1-i]-'0';
	for(int i=1;i<=len2;i++)
	b[i]=s2[len2-i]-'0';
	int t=0;
	for(int i=1;i<=len;i++)
	{
		int kk=a[i]+b[i]+t;
		if(kk>=10)
		{
			t=1;
			c[i]=kk%10;
		}
		else
		{
			t=0;
			c[i]=kk;
		}
	 }
	 string ss="";
	 if(t==1)
	 {
	 	for(int i=len+1;i>=1;i--)
	 	ss+='0'+c[i];
	  }
	  else 
	 	{
	 		for(int i=len;i>=1;i--)
	 		ss+='0'+c[i];
		 } 
		 return ss;
}
string Multiply(string s1,int jj)//旧数据 新数据 
{
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	memset(c,0,sizeof(c));
	sm.str("");
	sm.clear();
	sm<<jj;
	string s2=sm.str();
	string ss="";
	int len1=s1.size();
	int len2=s2.size();
    for(int i=1;i<=len1;i++)
	a[i]=(s1[len1-i]-'0');
	for(int j=1;j<=len2;j++)
	b[j]=(s2[len2-j]-'0');
	int t=0;//
	for(int i=1;i<=len1;i++)
	{
		int k=++t;//起点 
		for(int j=1;j<=len2;j++)
		{
			int f=a[i]*b[j];
			c[k++]+=f;
		}
	 }
	 for(int i=1;i<=len1+len2+1;i++)
	 {
	 	int y=c[i]/10;
	 	//cout<<y<<" ";
	 	c[i]=c[i]%10;
	 	c[i+1]+=y;
	  }
	 int tt;
	 bool bb=false;
	 for(int i=len1+len2;i>=1;i--)
	 {
	 	if(c[i]!=0)
		 {
		 	bb=true;
		 	tt=i;
		 	break;
		 };
	  } 
	  if(!bb)cout<<0<<endl;
	  for(int i=tt;i>=1;i--)
	  ss+=('0'+c[i]);
	  return ss;
}
int main()
{
	//递归计算阶乘
	int n;
	cin>>n;
	string sold="0";
	for(int i=n;i>=1;i--)
	{
		//求阶乘和
		string old="1";
		for(int j=i;j>=1;j--)
		{
			old=Multiply(old,j);
		 }
		 sold=Add(sold,old);
	}
	//cout<<Multiply("355687428096000",15)<<endl;
	cout<<sold<<endl;
	return 0;
 }  
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风炑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值