飞道的博客

【1041】 Computer Transformation 【递推 / 高精加f法】

212人阅读  评论(0)


http://acm.hdu.edu.cn/showproblem.php?pid=1041
唠嗑,吐槽
不得不说杭电里面的题真的新颖,我在其它oj上刷了不少题,最近才开始刷HDUoj,
以前觉得这个oj是英文的不爽,因为我的英语垃圾到了极致。
为了准备ACM省赛,只能硬着头皮刷杭电里的题,一来提升思维,而来能看懂英文题。
这道题题意没看懂,于是用了翻译软件翻译,结果翻译软件太坑了,弄的我不知道题目啥意思。
后来还是看英文一个个翻译才知道题意。

题意: 就是递推的变化,最后看一下有多少个 “00" 。

首先我们分析一下这该如何求?

第一种方法纯模拟: 按照题目的要求模拟。你会发现这样时间复杂度太高了 O(2n) 绝对的TLE 加 MLE。

第二种方法用算法来算: 你会发现这也没有考察啥算法。

于是,结果就是打表找规律。

模拟的代码:

#include<cstdio>
#include<iostream>
using namespace std;
int main(void) 
{
   
	int n;
	while(cin>>n)
	{
   
		string s="1";
		string ans;
		while(n--)
		{
   
			for(int i=0;i<s.size();i++)
			{
   
				if(s[i]=='0') ans+="10";
				else ans+="01";
			}
			s=ans;
			ans.clear();
		}
		cout<<s<<endl;
	}
	return 0;
}


规律十分的明显: s[ i ]= s[ i -1 ] + 2 x s [ i - 2 ]
分析后发现我们要用高精来算

注意要先将结果算出来,再输入n。
避免每输入一个n 计算一次,这样重复做了好几遍,会 TLE。

#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;

vector<int> mul(vector<int> &A,int d)
{
   
	vector<int> C; int t=0;
	for(int i=0;i<A.size()||t;i++)
	{
   
		if(i<A.size()) t+=A[i]*d;
		C.push_back(t%10);
		t/=10;
	}
	while(C.size()>1&&C.back()==0) C.pop_back();
	return C;
}
vector<int> add(vector<int> &A, vector<int> &B)
{
   
	vector<int> C; int  t=0;
	for(int i=0;i<A.size()||i<B.size();i++)
	{
   
		if(i<A.size()) t+=A[i];
		if(i<B.size()) t+=B[i];
		C.push_back(t%10);
		t/=10;
	}
	if(t) C.push_back(1);
	return C;
}
int main(void)
{
   
	int n;
	vector<int>A[1005];
	A[0].push_back(0);
	A[1].push_back(0);
	A[2].push_back(1); 
	for(int i=3;i<=1001;i++)
	{
   
		A[i]=mul(A[i-2],2);
		A[i]=add(A[i],A[i-1]);
	} 
	while(cin>>n)
	{
   
		
		for(int i=A[n].size()-1;i>=0;i--) cout<<A[n][i];
		cout<<endl;
	}
	return 0;
}

其实写一个加法的模板就行了。

#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;
vector<int> add(vector<int> &A, vector<int> &B)
{
   
	vector<int> C; int  t=0;
	for(int i=0;i<A.size()||i<B.size();i++)
	{
   
		if(i<A.size()) t+=A[i];
		if(i<B.size()) t+=B[i];
		C.push_back(t%10);
		t/=10;
	}
	if(t) C.push_back(1);
	return C;
}
int main(void)
{
   
	int n;
	vector<int>A[1005];
	A[0].push_back(0);
	A[1].push_back(0);
	A[2].push_back(1); 
	for(int i=3;i<=1001;i++)
	{
   
		A[i]=add(A[i-2],A[i-2]);
		A[i]=add(A[i],A[i-1]);
	} 
	while(cin>>n)
	{
   
		
		for(int i=A[n].size()-1;i>=0;i--) cout<<A[n][i];
		cout<<endl;
	}
	return 0;
}

转载:https://blog.csdn.net/bettle_king/article/details/116483610
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场