Nonfibonacci numbers

一,题目

链接:Nonfibonacci numbers - Gym 102439H - Virtual Judge (csgrandeur.cn) 

二,思路

1,从1到n找到所有满足其数位上的子序列不是斐波那契数列里的数,显然,找到一个数,而且这个数的子序列是斐波那契的数,这种操作正常人是不可能会去做的,毕竟n等于1e18,所以有什么诀窍呢,遇事不决先打表,下面是从小到大的一百个斐波那契数列(包括因超过64bit位而输出出不正确的数),然后你会惊奇的发现,每个数的数位肯定包含1,2,3,5,8其中一个数,所以我们只要判断一个数的数位上包不包括1,2,3,5,8就行了,简单吧?

1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
10946
17711
28657
46368
75025
121393
196418
317811
514229
832040
1346269
2178309
3524578
5702887
9227465
14930352
24157817
39088169
63245986
102334155
165580141
267914296
433494437
701408733
1134903170
1836311903
2971215073
4807526976
7778742049
12586269025
20365011074
32951280099
53316291173
86267571272
139583862445
225851433717
365435296162
591286729879
956722026041
1548008755920
2504730781961
4052739537881
6557470319842
10610209857723
17167680177565
27777890035288
44945570212853
72723460248141
117669030460994
190392490709135
308061521170129
498454011879264
806515533049393
1304969544928657
2111485077978050
3416454622906707
5527939700884757
8944394323791464
14472334024676221
23416728348467685
37889062373143906
61305790721611591
99194853094755497
160500643816367088
259695496911122585
420196140727489673
679891637638612258
1100087778366101931
1779979416004714189
2880067194370816120
4660046610375530309
7540113804746346429
-6246583658587674878
1293530146158671551
-4953053512429003327
-3659523366270331776
-8612576878699335103
6174643828739884737
-2437933049959450366

三,代码

#define _CRT_SECURE_NO_WARNINGS 1
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<math.h>
#include<cmath>
#include<string>
#include<unordered_map>
#include<set>
#include<vector>
#include<queue>
#include<cstring>
#include<string>
#include<iostream>
using namespace std;
#define endl '\n'
#define int long long
int arr[100] = { 0 }, book[100][10000] = { 0 };
int dfs(int pos, int limit, int lead, int sum)
{
	if (pos == 0) return 1;
	if (!limit && !lead && book[pos][sum] != -1) return book[pos][sum];
	int maxn = limit ? arr[pos] : 9, ans = 0;
	for (int i = 0; i <= maxn; ++i)
	{
		if (i == 1 || i == 2 || i == 3 || i == 5 || i == 8) continue;
		ans += dfs(pos - 1, limit && i == maxn, lead && i == 0, sum + i);
	}
	if (!limit && !lead) book[pos][sum] = ans;
	return ans;
}
int handle(int num)
{
	memset(book, -1, sizeof(book));
	int cnt = 0;
	while (num) arr[++cnt] = num % 10, num /= 10;
	return dfs(cnt, 1, 1, 0);
}
signed main()
{
	ios::sync_with_stdio(0); cout.tie(0); cin.tie(0);
	int t;
	cin >> t;
	while (t--)
	{
		int num;
		cin >> num;
		cout << handle(num) << endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值