zjut 1740 Find x 从此题推广到求一个数的N次方的小数精度问题

这题题意就是给定一个1~21的整数,求出其开三次方的值,保留小数点100位。这题大概的做法就是先由普通开三次方确认一个头,然后通过大数乘逐位逼近结果,因为小数比较麻烦,所以只能每次逼近一位,在逼近的字符串s1上+‘0’,给定的整数+“000”即可。因为要四舍五入,先逼近到101位,然后对最后一位进行判断修改即可。但是我逼近的方法是暴力顺序法,每个数字的复杂度大约是100位×10个数字×大数乘中100×100×2的复杂度,大约是20000000的复杂度,还不算调用函数等时间,所以随便取一个就超时了。。。只好导出来。即使顺序用二分也就缩短到3000000左右,数字一多还是不给力。用傅立叶变换处理大数乘的话,100^1.59次方左右的复杂度,即约为502654一个数字。如果要处理100以内的数字,就50000000的预处理量,勉强可以应付1s的时间。不过至此可以得到以后求此类题的一个方法。因为开3次方用我已知的方法去优化也只能处理到100以内的数字极限了,那么基本以后出到类似题只要不是防AK题类的题,直接用笨办法跑出来然后直接预处理就OK了。下面注释中卫21个预处理的代码。用时大约半分钟。。。下面是AC代码。
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<cstdio>
#include<cmath>
#include<fstream>
using namespace std;

/*ofstream fout("out.txt");
string BigNumMultiply(string s1,string s2)
{
	int i,j;
	reverse(s1.begin(),s1.end());
	reverse(s2.begin(),s2.end());
	vector<int> v(s1.length()+s2.length(),0);
	for(i=0;i<s1.length();i++)
	{
		for(j=0;j<s2.length();j++)
		{
			v[i+j]+=int(s1[i]-'0')*int(s2[j]-'0');
		}
	}
	int jinwei=0;
	string s,ss;
	for(i=0;i<v.size();i++)
	{
		int t=v[i]+jinwei;
		if(i==v.size()-1 && t==0) break;
		jinwei=t/10;
		s+=char(t%10+'0');
	}
	if(jinwei) s+=char(jinwei+'0');
	//cout<<s<<endl<<endl;
	//s=s.substr(s.find_first_not_of('0'));
	reverse(s.begin(),s.end());
	s=s.substr(s.find_first_not_of('0'));
	return s;
}*/

int main()
{
	/*string que;
	int i,j,k;
	for(k=1;k<=21;k++)
	{
	que.clear();
	int tk=k;
	while(tk)
	{
	que+=tk%10+'0';
	tk/=10;
	}
	reverse(que.begin(),que.end());
	//cout<<que<<endl;
	//continue;
	string s1,s2;
	if(que.length()==1)	
	s1+=int(pow(int(que[0]-'0'),1.0/3.0))+'0';
	else
	s1+=int(pow(int(que[1]-'0'+(que[0]-'0')*10),1.0/3.0))+'0';
	int jishu=1;
	while(jishu!=102)
	{
	que+="000";
	s1+='0';
	while(1)
	{
	string st=BigNumMultiply(s1,BigNumMultiply(s1,s1));
	//cout<<st<<" "<<que<<endl;
	if(st.length()>que.length()) {s1[jishu]--;break;}
	else if(st.length()==que.length() && st>que) {s1[jishu]--;break;}
	else s1[jishu]++;
	}
	jishu++;
	}
	if(s1[s1.length()-1]>='5')
	{
	for(i=s1.length()-2;i>=0;i--)
	if(s1[i]!='9') {s1[i]++;break;}
	else s1[i]='0';
	}
	s1.erase(s1.length()-1,1);
	fout<<s1[0]<<'.'<<s1.substr(1)<<endl;
	}*/
	string res[21]={
		"1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
		"1.2599210498948731647672106072782283505702514647015079800819751121552996765139594837293965624362550942",
		"1.4422495703074083823216383107801095883918692534993505775464161945416875968299973398547554797056452567",
		"1.5874010519681994747517056392723082603914933278998530098082857618252165056242191732735442132622209570",
		"1.7099759466766969893531088725438601098680551105430549243828617074442959205041732162571870100201890022",
		"1.8171205928321396588912117563272605024282104631412196714813342979313097394593018656471417041264170721",
		"1.9129311827723891011991168395487602828624390503458757662106476404472342761792307560075254414772857099",
		"2.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
		"2.0800838230519041145300568243578853863378053403732621096975910802001063113972687736060566367907574867",
		"2.1544346900318837217592935665193504952593449421921085824892355063464111066483408001854415035432432761",
		"2.2239800905693155211653633767221571965186991280969230556993458086604009830829759744897580544816262737",
		"2.2894284851066637356160844238793540178318138415758621441981043481313485980484283008752163220618340911",
		"2.3513346877207574895000163399569145269158419834621751050402543115883426809965668498079116042028440641",
		"2.4101422641752299861283696676032728953545812899808676541641397104132917269225938338226115162268134672",
		"2.4662120743304701014916113231545890427354844866280537601787874102933769529228974632162987026643460501",
		"2.5198420997897463295344212145564567011405029294030159601639502243105993530279189674587931248725101883",
		"2.5712815906582353554531872087397261164279016324546962598480223762199399330306701503243515304456515102",
		"2.6207413942088966071416612804419962702394276457236317251027738057286998191960421088284558259890735978",
		"2.6684016487219448673396273719708303350958785691831018656642135869457939716720597163166815931005165410",
		"2.7144176165949065715180894696794892048051077694890969572843654428033085563287658494871973768515010450",
		"2.7589241763811206694657911083585215822527120860389360328065925021627991410870437379126321585244375545"};
	int n;
	scanf("%d",&n);
	while(n--)
	{
		int m;
		scanf("%d",&m);
		printf("%s\n",res[m-1].c_str());
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值