F - 借仙书 [PSA]
Goran希望在仙界图书馆借一本书。这本书在仙界图书馆分为了两版发行,分别是a版和b版。这本书非常热门,图书馆的存量也非常大,并且摆放时也有规律:第0号书柜放的是a版,第1号书柜放的是b版,对于第k(k>1)个柜子,书的摆放方式就是重复将它前边两个书柜的排放方式,例如前几个书柜的顺序为:a,b,ab,bab,abbab,bababbab,abbabbababbab,...
当Goran在第N号书柜中选择其中的第k本书时,请你帮他判断这本书究竟是a版还是b版。(书柜从0开始编号,书柜中的书从1开始编号)
数据输入
第1行一个整数T,表示接下来Goran要选T次书。
接下来有T行,每行2个由空格分隔的整数N,K,表示Goran在第N号书柜选择第K本书
- 1≤T≤100
- 1≤N≤50
- k不超过当前书柜中书的数量,并且k≥1
数据输出
数据输出
输出有T行,每行输出字符a或b,表示对于Goran每次选的书,这本书是a版还是b版
样例
输入样例
4
0 1
1 1
3 2
7 7
输出样例
a
b
a
a
这个题,一开始我很老实的将S[i]=s[i-2]+s[i-1],结果运行了毫不意外的内存溢出
fine,然后想是不是String存储比较占地方,考虑用一个Long/Double来存其中的数据,简单算了一下,发现第50位的字符串长度要有10的11次方那么大(用String每个字符占1字节的话,需要11.7GB来存储这个字符串。即便将a,b两状态压缩成1bit,也仍需要1.47GB)然后考虑换BigInteger...但要对一个大数求其长度,实在是一个很费劲的事,感觉又可能会超时?主要也是转念一想,C++里面可没有大数,那玩C++的人可怎么做,于是瞬间感觉自己的思路走错了...赶紧换思路
fianlly,开始想规律把~其实看到这个题我就知道,要不就是贪心+暴力,要不是就是找规律,找组成规律,数学规律,解的规律。
如果s[i-2]的长度为L1,s[i-1]的长度为L2,显然s[i]的长度为L1+L2
那么在i中的第k的字符,就跟L1和L2有关了:
if k<=L1
i,k其实就是s[i-2]中的第k个
else
i,k其实就是s[i-1]中的第k-L1个
如此递归下去即可~
代码很简单:找到规律就可以了
import java.util.Scanner;
public class Main{
static int ans = 0;
static int T,n,k;
static int[] s = new int[51];
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
T = sc.nextInt();
s[0] = s[1] =1;
for (int i = 2; i < s.length; i++) {
s[i] = s[i-2]+s[i-1];
}
while(T-- !=0) {
n= sc.nextInt();
k = sc.nextInt();
ans = f(n,k);
if(ans==1)
System.out.println('a');
else if(ans==2)
System.out.println('b');
}
}
private static int f(int n, int k) {
if(n==0)
return 1;
if(n==1)
return 2;
if(k <= s[n-2]) {
return f(n-2,k);
}else {
return f(n-1,k-s[n-2]);
}
}
}
递归也是有规律的,很多题,尤其像这种组成很明显有某种结构的,一般都是通过规律解题,一般都暴力不出来(偶尔能贪心出来)
总之,还是注意分析解的结构,特征。
另外心态要好,做题前就想几种可能的解题思路,当发现自己走入误区了,立刻换准备好的新思路。(不要让大脑逻辑爆炸进入混沌...)