题目链接:https://ac.nowcoder.com/acm/contest/3674
A - The GCD of Fibonacci Numbers
对于两个斐波那契数的最大公因数,有一个公式:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int gcd(int a, int b)
{
if (b == 0) return a;
return gcd(b, a % b);
}
int f[50] = {0, 1, 1};
int main(void)
{
for (int i = 3; i <= 45; i++)
f[i] = f[i - 1] + f[i - 2];
int t, m, n;
scanf("%d", &t);
while (t--){
scanf("%d%d", &m, &n);
int gc = gcd(m, n);
printf("%d\n", f[gc]);
}
return 0;
}
G - Buying Keys
如果能够花完手上的钱,输出最少能购买的钥匙数,如果不能花完手上的钱,输出"orz"
买钥匙有两种方法:三元一把,十元三把,所以我们要尽可能多的以10元的方式购买钥匙才能买到更少的钥匙。
先一把一把的买,可能有两种情况:
1)最后手上的钱是10的整倍数(包括0),此时以10元的方式花完所有钱。
2)最后手上的钱小于3元,这样说明花不完手上的钱。
#include <cstdio>
int main(void)
{
int n, ans = 0;
scanf("%d", &n);
while (true){
if (n % 10 == 0){
ans += (n / 10) * 3;
printf("%d\n", ans);
return 0;
}
if (n < 3){
printf("orz\n");
return 0;
}
n -= 3;
ans += 1;
}
return 0;
}
H - Dice
第一轮使用1元,第二轮使用2元,第三轮使用4元,依次类推。
最多玩n局,只要n局中有一局胜利,就会赢钱,且不会进行下面的游戏。n局全输的话才会亏损。
求赢钱的概率
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int main(void)
{
int t, n;
double ans, p;
scanf("%d", &t);
while (t--){
scanf("%d", &n);
ans = 0;
p = 0.5;
for (int i = 0; i < n; i++){
ans += p;
p /= 2;
}
printf("%.4lf\n", ans);
}
return 0;
}
L - Special number
求给出的区间中有多少个数能被少于三个数整除。
比如1 只能被自己整除,满足条件。2只能被1和2整除,满足条件
一开始用埃氏筛法做,一直提示段错误。后来使用的朴素算法
#include <cstdio>
#include <cmath>
using namespace std;
bool judge(int n)
{
if (n == 0)
return false;
else if (n == 1)
return true;
for (int i = 2; i <= sqrt(n); i++){
if (n % i == 0){
return false;
}
}
return true;
}
int main(void)
{
int l, r;
scanf("%d%d", &l, &r);
int ans = 0;
for (int i = l; i <= r; i++){
if (judge(i))
ans++;
}
printf("%d\n", ans);
return 0;
}
M - XOR sum
一位大佬的代码,利用公式求出前缀和
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll f(ll x)
{
if (x % 4 == 1) return 1;
else if (x % 4 == 2) return x + 1;
else if (x % 4 == 3) return 0;
else return x;
}
int main(void)
{
ll l, r;
cin >> l >> r;
cout << (f(l - 1) ^ f(r)) << endl;
return 0;
}