牛客周赛 Round 6
牛客周赛 Round 6
A-游游的数字圈_牛客周赛 Round 6 (nowcoder.com)
枚举即可
#include <bits/stdc++.h> #define int long long using namespace std; signed main(){ ios::sync_with_stdio(false); cin.tie(nullptr); string s; cin >> s; int ans = 0; for(int i = 0;i < s.size();i ++){ ans += (s[i] == '0' || s[i] == '6' || s[i] == '9'); ans += (s[i] == '8') * 2; } cout << ans << '\n'; return 0; }
B-竖式乘法_牛客周赛 Round 6 (nowcoder.com)
\(a\)每次去乘\(b\)的每一位数累加即可
#include <bits/stdc++.h> #define int long long using namespace std; signed main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int T; cin >> T; while(T--){ int ans = 0; int a,b; cin >> a >> b; while(b){ ans += b % 10 * a; b /= 10; } cout << ans << '\n'; } return 0; }
C-游游的数值距离_牛客周赛 Round 6 (nowcoder.com)
若令\(|x! \times y - y - n|=0\),我们可以得到\(y = \frac{n}{x! - 1}\),因此我们可以去枚举\(x\),从而得到\(y\),且这里是向下取整的,所以正确答案要么是 \(y\) 要么是 \(y+1\) ,又因为\(x!\)是一个很大的数,所以我这里枚举到\(10\)就行了
#include <bits/stdc++.h> #define int long long using namespace std; signed main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; int ansx = 1,ansy = 1,fac = 2,ans = n; for(int i = 3;i <= 10;i ++){ fac *= i; int y = n / (fac - 1); int val = abs(y * (fac - 1) - n); if(y > 0 && y != 2 && val <= ans){ ans = val, ansx = i, ansy = y; } y++; val = abs(y * (fac - 1) - n); if(y > 0 && y != 2 && val <= ans){ ans = val, ansx = i, ansy = y; } } cout << ansx << ' ' << ansy << '\n'; return 0; }
D-游游的k-好数组_牛客周赛 Round 6 (nowcoder.com)
要使得所有长度区间为\(k\)的区间和相等,最简单的方法就是让每隔\(k\)个数字相等,这样每长度为\(k\)的第\(i\)个数字都相同,那自然区间和也相等,所以我们先算出每隔\(k\)隔数字的最大值,然后计算每\(k\)个数字到其最大值差多少,我们最多补\(x\),如果说差的比我们能补得还多,那我们不能把它变为一个\(k-\)好数组,否则我们尽量的把多出来的数分到所有的长度为\(k\)的区间内的第\(i\)个数字上,最后就是看分配到哪个位置上能得到最大值
#include <bits/stdc++.h> #define int long long using namespace std; signed main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int T; cin >> T; while(T--){ int n,k,x; cin >> n >> k >> x; vector<int> a(n),mx(k); for(int i = 0;i < n;i ++){ cin >> a[i]; mx[i % k] = max(mx[i % k], a[i]); } int sum = 0; for(int i = 0;i < n;i ++) sum += mx[i % k] - a[i]; if(sum > x){ cout << -1 << '\n'; continue; } x -= sum; int ans = 0; for(int i = 0;i < k;i ++){ int now = n / k + (n % k > i); ans = max(ans, mx[i] + x / now); } cout << ans << '\n'; } return 0; }
E-小红的循环节长度_牛客周赛 Round 6 (nowcoder.com)(数学)
本题参考:
怎样快速找到一个可表为无限循环小数的分数的循环节位数? - 知乎 (zhihu.com)
欧拉函数φ(n)的计算及欧拉定理 - 知乎 (zhihu.com)
牛客周赛 Round 6_m0_73618658的博客-CSDN博客
借鉴第一篇知乎大佬回答:假设一个真分数可以表示为 \(\frac{m}{n}, m<n\) ,\(m\)与\(n\)是互素的。 如果\(n\)的因子只含有2和5,也就是说 \(n=2^a5^b\) 那么我们就可以通过在分子分母上同时乘以适合数量的2或者5,将分母表示为10的次方的形式, \(\frac{m}{n}=\frac{p}{10^c}\) , 这就说明这个分数是有限小数。如果\(n\)中完全不含有2和5,那么\(n\)与10互素,根据初等数论中的欧拉定理,存在一个整数 \(a\) ,满足 \(10^{a}\equiv1(\mathrm{mod} \; n)\) ,也就是 \(10^a-1\) 可以整除\(n\). 所以可以通过分子分母同时乘以一些因子,将分母变成\(9999...9\)的形式, \(\frac{m}{n}=\frac{p}{10^a-1}=\frac{p}{9\cdots 9}\) 。这时9的个数 \(a\) 就是循环节的位数,分子上的整数通过在前面补0,使得分子分母位数一致,此时分子就是循环节。另外还有一种情况,就是 \(n\) 中既包含 2,5 也包含其他素因子, \(n=2^a 5^b q_1^{c_1}q_2^{c_2}\cdots\) 那么,我们可以补充2和5,凑出10的整次方,\(\frac{m}{n}=\frac{p}{10^dq}\) , \(q\)与10互素。然后 \(p\) 可能大于 \(q\) , 令 \(p=kq+r,r<q\) , 注意k是可以等于0的。于是 \(\frac{m}{n}=\frac{1}{10^d}(k+\frac{r}{q})=\frac{k}{10^d}+\frac{1}{10^d}\frac{r}{q}\) , 然后这就是一个部分循环小数,从第 \(d+1\) 位开始循环,循环节由 \(\frac{r}{q}\) 经前面的第二种情况来确定。
所以我们可以先对分母化简,然后去计算分母中2和5的数量,数量多的就是循环节前面部分的长度了,然后对分母的因数去遍历找到满足\(10^{i}\equiv1(\mathrm{mod} \; q)\)或者\(10^{\frac{phi(q)}{i}}\equiv1(\mathrm{mod} \; q)\),取最短的循环节即可
#include <bits/stdc++.h> using i64 = long long; using i128 = __int128; using namespace std; i64 ksm(i128 a, i64 b, i64 p) { i128 res = 1; while (b) { if (b & 1)res = res * a % p; b >>= 1; a = a * a % p; } return res; } i64 phi(i64 x) { i64 i; i64 res = x; for (i = 2; i * i <= x; i++) { if (x % i == 0) { res = res / i * (i - 1); while (x % i == 0)x /= i; } } if (x > 1)res = res / x * (x - 1); return res; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); i64 p,q,c2 = 0, c5 = 0; cin >> p >> q; q /= gcd(p,q); while(q % 2 == 0) q/= 2, c2 ++; while(q % 5 == 0) q/= 5, c5 ++; if(q == 1){ cout << "-1\n"; return 0; } i64 te = phi(q),ans = 1e16; for(i64 i = 1;i * i <= te;i ++){ if(te % i == 0){ if(ksm((i128)10, i ,q) == 1) ans = min(ans, i); if(ksm((i128)10, te / i, q) == 1) ans = min(ans, te / i); } } cout << max(c2, c5) << ' ' << ans << '\n'; return 0; }
本文作者:Ke_scholar
本文链接:https://www.cnblogs.com/Kescholar/p/17612626.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步