21-22(1)第4次线上赛题解
作者:互联网
虽然这场我陪跑了(被教育了)
但是题解这东西想写就写了
没出现的数字
题意:
判断一个正整数的每一位数字中是否出现了0~9这10个数字,统计有多少个数字没出现过。
题解:
使用bool数组标记是否出现过
- 使用memset初始化
- 使用string类型读取数据,用s[i]-'0'作为下标
上板子:
using namespace std; bool num[10]; int main() { int T;cin >> T; while (T--) { int ans = 0; memset(num, 0, sizeof(num));//初始化num数组 string s; cin >> s; for (int i = 0;i < s.length();i++) num[s[i] - '0'] = 1; for (int i = 0;i < 10;i++) if (!num[i])ans++; cout << ans << endl; } return 0; }
喜欢的数字
题意:
规定 tql 喜欢 2 的整数次幂以及 2 的整数次幂 -1
给定一个数 num,求距离 num 最近的符合规定的数
题解:
进行预处理,记录所有案例范围内 tql 喜欢的数字
注:2^17=131,072,所以这题其实运算量不大,应该暴力也能AC
- 使用set容器存储(可以用数组代替,记得对数组使用sort排序)
- 使用lower_bound(begin,end,num)查找(lower_bound要对已经排序的数组使用)
上板子:
using namespace std; int main() { set<int>s; int a = 1; for (int i = 1;i < 18;i++) { a <<= 1; s.insert(a - 1); s.insert(a); } int t;cin >> t; int num; while (t--) { cin >> num; int num1 = *lower_bound(s.begin(), s.end(), num);//二分查找,返回大于等于num的值的最小地址 int num2 = (num1 + 1 >> 1);//注意理解这里的num为什么要+1,可以自己代一组数据进去试试 cout << (num1 - num < num - num2 ? num1 : num2) << endl;//输出距离较小的值 } return 0; }
OJ新人
题意:
问最优的做题顺序下的小分比当前顺序下的小分,能少多少?
题解:
- 计算当前总分sum1
- 计算每道题的用时并记录到数组a[]
- 对a进行排序
- 从用时最短的题目开始做
斐波那契汤
题意:
一个数列满足:vi=vi-1/2+vi-2/3,i>=3;另外,每到5的倍数会 + c ,现给定前两项与 c 求第 m 项
题解:
暴力迭代就是了
上板子:
using namespace std; typedef long long ll; int main() { int t;cin >> t; while (t--) { int a, b, c, m; cin >> a >> b >> c >> m; if (m == 1)cout << a << endl; else if (m == 2)cout << b << endl; else { for (int i = 1;i <= m;i++) { if (i == 1 || i == 2)continue; a = a / 3 + b / 2; if (i % 5 == 0)a += c; swap(a, b); } cout << b << endl; } } return 0; }
公共质因数的和
题意:
求a和b的所有公共质因数之和。
题解:
先求a b的最大公因数,然后求最大公因数的质因数,然后相加求和
主要是方法的问题,其实代码实现没有很大的难度
上板子:
using namespace std; typedef long long ll; int gcd(int a, int b) { return !b ? a : gcd(b, a % b); } bool isPrime(int x) { if (x < 2) return false; for (int i = 2;i <= sqrt(x);i++) if (x % i == 0) return false; return true; } int main() { int t;cin >> t; while (t--) { int num1, num2; ll sum = 0; cin >> num1 >> num2; int num = gcd(num1, num2); for (int i = 2;i <= sqrt(num);i++) { if (num % i == 0 && isPrime(i))sum += i; if (num / i == i)continue; if (num % (num / i) == 0 && isPrime(num / i))sum += num / i; } if (isPrime(num))sum += num; cout << sum << endl; } return 0; }
最大乘积
题意:
把一个正偶数m拆分成两个质数之和(可以是相同的质数),输出这两个质数可能的最大乘积。
题解:
- 使用埃氏筛计算范围内的全部质数
- 从m/2开始算(两数和固定情况下,两数越接近两数乘积越大)
上板子:
using namespace std; typedef long long ll; const int N = 1000007; bool isprime[N]; int main() { memset(isprime, 1, sizeof(isprime)); for (int i = 2; i * i < N; i++) { if (isprime[i]) { for (int j = i * i; j < N; j = j + i) { isprime[j] = 0; } } } int T;cin >> T; while (T--) { ll num; cin >> num; for (ll i = num / 2;i > 1;i--) { if (isprime[i] && isprime[num-i]) { cout << i * (num-i) << endl; break; } } } return 0; }
制作:BDT20040
PS:这次线上赛被教育了,看到大佬30分钟AK我直接心态炸了嗐
标签:21,int,题解,cin,num,isprime,次线,题意 来源: https://www.cnblogs.com/liubaili/p/15643774.html