Fibonacci字符串定义如下:
例如,前几个Fibonacci字符串是
a
bc
abc
bcabc
abcbcabc
给定行和偏移量的目标是确定该偏移处的字符。更正式地说:
输入:由空格分隔的两个整数 - K和P(0
9 ),(&lt;P≤10 9 < / sup>),其中K是Fibonacci字符串的行号,P是行中的位置号。 输出:相关测试的所需字符:“a”,“b”或“c”。如果P大于第k行(K≤10 9 ),则必须推导出“无解”
示例:
输入: 18 58
输出: a
我写了这段代码来解决问题:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
int k, p;
string s1 = "a";
string s2 = "bc";
vector < int >fib_numb;
fib_numb.push_back(1);
fib_numb.push_back(2);
cin >> k >> p;
k -= 1;
p -= 1;
while (fib_numb.back() < p) {
fib_numb.push_back(fib_numb[fib_numb.size() - 1] + fib_numb[fib_numb.size() - 2]);
}
if (fib_numb[k] <= p) {
cout << "No solution";
return 0;
}
if ((k - fib_numb.size()) % 2 == 1)
k = fib_numb.size() + 1;
else
k = fib_numb.size();
while (k > 1) {
if (fib_numb[k - 2] > p)
k -= 2;
else {
p -= fib_numb[k - 2];
k -= 1;
}
}
if (k == 1)
cout << s2[p];
else
cout << s1[0];
return 0;
}
这是对的吗?你会怎么做?
答案 0 :(得分:14)
答案 1 :(得分:1)
我想你的一般想法应该没问题,但是我不知道你的代码将如何处理更大的K值,因为数字会迅速变大,即使使用大型整数库,它也可能永远需要准确地计算斐波那契(10 ^ 9)。
幸运的是,您只被问到前10 ^ 9个字符。该字符串将在第44行(f(44)= 1134903170)上达到许多字符。
如果我没有弄错的话,那里的前10 ^ 9个字符将简单地在第44行和第45行的前缀之间交替,因此在伪代码中:
def solution(K, P):
if K > 45:
if K % 2 == 0:
return solution(44, P)
else:
return solution(45, P)
#solution for smaller values of K here
答案 2 :(得分:0)
k
- fibo字符串的大小来再次测试p
因为如果检查成功,你无论如何都要计算它。当然,只要k
变大,就可能出现溢出问题(fibo字符串的长度是索引n
的指数函数...)。
#include <iostream>
#include <string>
using namespace std;
string fibo(unsigned int n)
{
if (n == 0)
return "a";
else if (n == 1)
return "bc";
else
return fibo(n - 2) + fibo(n - 1);
}
int main()
{
unsigned int k, p;
cin >> k >> p;
--k;
--p;
string fiboK = fibo(k);
if (p > fiboK.size())
cout << "No solution" << endl;
else
cout << fiboK[p] << endl;
return 0;
}
编辑:好的,我现在看到你的观点,即检查k
- 字符串p
的哪一部分(即字符串k - 2
或k - 1
,并在需要时更新p
。当然,这是做到这一点的好方法,因为正如我上面所说,我天真的解决方案会爆炸得太快。
从算法的角度来看,你的方式对我来说是正确的(节省内存和复杂性)。
答案 3 :(得分:0)
我会计算出第K个Fibonacci字符串,然后检索它的第P个字符。这样的事情:
#include <iostream>
#include <string>
#include <vector>
std::string FibonacciString(unsigned int k)
{
std::vector<char> buffer;
buffer.push_back('a');
buffer.push_back('b');
buffer.push_back('c');
unsigned int curr = 1;
unsigned int next = 2;
while (k --)
{
buffer.insert(
buffer.end(),
buffer.begin(),
buffer.end());
buffer.erase(
buffer.begin(),
buffer.begin() + curr);
unsigned int prev = curr;
curr = next;
next = prev + next;
}
return std::string(
buffer.begin(),
buffer.begin() + curr);
}
int main(int argc, char** argv)
{
unsigned int k, p;
std::cin >> k >> p;
-- p;
-- k;
std::string fiboK = FibonacciString(k);
if (p > fiboK.size())
std::cout << "No solution";
else
std::cout << fiboK[p];
std::cout << std::endl;
return 0;
}
它使用的内存比你的版本多,因为它需要在每个瞬间存储第N和第(N + 1)个斐波那契字符串。但是,由于它非常接近定义,因此它适用于每个值。
当k
较大且p
较小时,您的算法似乎存在问题。测试fib_num[k] < p
会使用k = 30
和p = 1
取消引用数组范围之外的项目,不是吗?
答案 4 :(得分:0)
我做了另一个例子,其中每个相应数量的Fibonnaci系列对应于alfabet中的字母。所以1是a,2是b,3是c,5是e ...等:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string a = "abcdefghijklmnopqrstuvwxyz"; //the alphabet
string a1 = a.substr(0,0); string a2 = a.substr(1,1); string nexT = a.substr(0,0);
nexT = a1 + a2;
while(nexT.length() <= a.length())
{
//cout << nexT.length() << ", "; //show me the Fibonacci numbers
cout << a.substr(nexT.length()-1,1) << ", "; //show me the Fibonacci letters
a1 = a2;
a2 = nexT;
nexT = a1 + a2;
}
return 0;
}
输出: a,b,c,e,h,m,u,