nowcoderG 小国的复仇
题意:一开始s1=1,s2=1,每次有两种操作,1:s1=s1+s2,s2=s2 2:s1=s1*2,s2=s1,问最少几次能让S1变为n
题解:倒着推回来,可以发现n为素数,
if(n != 2*m) m = get(n-m);
n -= m;
#include<bits/stdc++.h> #define mk(a, b) make_pair(a, b) using namespace std; typedef long long ll; const int maxn = 200005, N = 1000010; int get(int x) { for(ll i=2; i*i<=x; ++i) if(x%i==0) return x/i; return 1; } bool isprime[N]; ll prime[N], num; void doprime(ll n){ ll i,j; num = 0; memset(isprime, true,sizeof(isprime)); isprime[1] = 0; for(i=2;i<=n;i++){ if(isprime[i]){ prime[num++] = i; for(j=i*i;j<=n;j+=i) isprime[j] = false; } } } int T, n, m, ans; int main() { doprime(1000000); scanf("%d", &T); while(T--){ scanf("%d", &n); m = get(n); if(((n-1)&n) == 0&&n>10) ans = 1; else ans = 0; while(n!=1){ if(isprime[n]){ ans += n-1; break; } ++ans; if(n != 2*m) n -= m, m = m; else n /= 2, m = get(n); } printf("%d\n", ans); } return 0; }
posted on 2018-04-21 18:10 2855669158 阅读(167) 评论(0) 编辑 收藏 举报