牛客周赛129
锐评
难度:F > E > D > C > B > A
A
题目链接:https://ac.nowcoder.com/acm/contest/127264/A
代码:
/*Don’t cut corners, don’t over-rely on AI. Stay grounded, and keep challenging yourself with every single problem.*/
#include <bits/stdc++.h>
//当遇到感觉可以写但总是卡壳的题时,不妨先冷静下来仔细思考。
//当把题目真正读懂的时候,你已经写出来了一半。
//学习他人的做法也是一种提升。
//过程是很痛苦,但唯有坚持。
//输入报错可能是数组边界问题,看下循环条件关于索引的位置有没有放反
using namespace std;
using i64 = long long;
using u64 = unsigned long long;
constexpr i64 INF = 998244353;
constexpr int N = 300005;
constexpr double IP = 2.7182818;
constexpr i64 MAXN = 1E6 + 7;
constexpr i64 MOD = 1E9 + 7;
i64 inv[1000009];
i64 f_inv[1000009];
i64 ksm(i64 x, i64 y){
i64 ans = 1;
while(y > 0){
if(y & 1){
ans = ans * x % MOD;
}
y >>= 1;
x = x * x % MOD;
}
return ans;
}
void inint(){
inv[0] = 1;
for(int i = 1;i <= 1000000; i++){
inv[i] = inv[i-1] * i % MOD;
}
f_inv[1000000] = ksm(inv[1000000], MOD-2);
for(int i = 999999; i >= 0; i--){
f_inv[i] = f_inv[i+1] * (i+1) % MOD;
}
}
i64 C(int n, int m){
if(n < m || n < 0 || m < 0) return 0;
return inv[n] * f_inv[n-m] % MOD * f_inv[m] % MOD;
}
i64 A(i64 n, i64 m){
i64 ans = 1;
for(int i = n;i >= n - m + 1; i--) ans = ans * i % MOD;
return ans;
}
template<class T>
void solve(){
int x;
std::cin >> x;
if(x == 1){
std::cout << "equal\n";
}else{
std::cout << "right\n";
}
}
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t=1;
// inint();
// cin>>t;
while(t--)
solve<int>();
return 0;
}
B
题目链接:https://ac.nowcoder.com/acm/contest/127264/B
代码:
/*Don’t cut corners, don’t over-rely on AI. Stay grounded, and keep challenging yourself with every single problem.*/
#include <bits/stdc++.h>
//当遇到感觉可以写但总是卡壳的题时,不妨先冷静下来仔细思考。
//当把题目真正读懂的时候,你已经写出来了一半。
//学习他人的做法也是一种提升。
//过程是很痛苦,但唯有坚持。
//输入报错可能是数组边界问题,看下循环条件关于索引的位置有没有放反
using namespace std;
using i64 = long long;
using u64 = unsigned long long;
constexpr i64 INF = 998244353;
constexpr int N = 300005;
constexpr double IP = 2.7182818;
constexpr i64 MAXN = 1E6 + 7;
constexpr i64 MOD = 1E9 + 7;
i64 inv[1000009];
i64 f_inv[1000009];
i64 ksm(i64 x, i64 y){
i64 ans = 1;
while(y > 0){
if(y & 1){
ans = ans * x % MOD;
}
y >>= 1;
x = x * x % MOD;
}
return ans;
}
void inint(){
inv[0] = 1;
for(int i = 1;i <= 1000000; i++){
inv[i] = inv[i-1] * i % MOD;
}
f_inv[1000000] = ksm(inv[1000000], MOD-2);
for(int i = 999999; i >= 0; i--){
f_inv[i] = f_inv[i+1] * (i+1) % MOD;
}
}
i64 C(int n, int m){
if(n < m || n < 0 || m < 0) return 0;
return inv[n] * f_inv[n-m] % MOD * f_inv[m] % MOD;
}
i64 A(i64 n, i64 m){
i64 ans = 1;
for(int i = n;i >= n - m + 1; i--) ans = ans * i % MOD;
return ans;
}
template<class T>
void solve(){
string s;
std::cin >> s;
string t = s;
reverse(t.begin(), t.end());
if(s == t){
std::cout << "equal\n";
}else if(t > s){
std::cout << "right\n";
}else{
std::cout << "left\n";
}
}
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t=1;
// inint();
// cin>>t;
while(t--)
solve<int>();
return 0;
}
C
题目链接:https://ac.nowcoder.com/acm/contest/127264/C
思路:
对每个数从小到大遍历,若x+1 >= k则金币 += c / 2;mp[x+1] += c / 2;
代码:
/*Don’t cut corners, don’t over-rely on AI. Stay grounded, and keep challenging yourself with every single problem.*/
#include <bits/stdc++.h>
//当遇到感觉可以写但总是卡壳的题时,不妨先冷静下来仔细思考。
//当把题目真正读懂的时候,你已经写出来了一半。
//学习他人的做法也是一种提升。
//过程是很痛苦,但唯有坚持。
//输入报错可能是数组边界问题,看下循环条件关于索引的位置有没有放反
using namespace std;
using i64 = long long;
using u64 = unsigned long long;
constexpr i64 INF = 998244353;
constexpr int N = 300005;
constexpr double IP = 2.7182818;
constexpr i64 MAXN = 1E6 + 7;
constexpr i64 MOD = 1E9 + 7;
i64 inv[1000009];
i64 f_inv[1000009];
i64 ksm(i64 x, i64 y){
i64 ans = 1;
while(y > 0){
if(y & 1){
ans = ans * x % MOD;
}
y >>= 1;
x = x * x % MOD;
}
return ans;
}
void inint(){
inv[0] = 1;
for(int i = 1;i <= 1000000; i++){
inv[i] = inv[i-1] * i % MOD;
}
f_inv[1000000] = ksm(inv[1000000], MOD-2);
for(int i = 999999; i >= 0; i--){
f_inv[i] = f_inv[i+1] * (i+1) % MOD;
}
}
i64 C(int n, int m){
if(n < m || n < 0 || m < 0) return 0;
return inv[n] * f_inv[n-m] % MOD * f_inv[m] % MOD;
}
i64 A(i64 n, i64 m){
i64 ans = 1;
for(int i = n;i >= n - m + 1; i--) ans = ans * i % MOD;
return ans;
}
template<class T>
void solve(){
i64 n, m, k;
std::cin >> n >> m >> k;
std::map<i64, i64> mp;
for(int i = 0;i < n; i++){
for(int j = 0;j < m; j++){
int x;
std::cin >> x;
if(x != 0)
mp[x] ++;
}
}
//mp[0] = 0;
i64 ans = 0, cost = 0, mm = 0;
for(auto &[x, c] : mp){
//c += mm;
//if(x == 0) continue;
if(c==0) break;
i64 cnt = c / 2;
cost += cnt;
if(cnt == 0) continue;
if(x + 1 >= k) ans += cnt;
//mm = cnt;
mp[x+1] += cnt;
//std::cout << c << " ";
}
std::cout << cost << " " << ans << "\n";
}
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t=1;
// inint();
// cin>>t;
while(t--)
solve<int>();
return 0;
}
D
题目链接:https://ac.nowcoder.com/acm/contest/127264/D
思路:
对于一个子串,如果我们要选择?101?,要想不改变他的块数,必须两边有一边与邻位相同,一边不相同。 还一种特殊情况就是所有字符全都翻转。所以总次数=1+一边相同总数*一边不相同总数
代码:
/*Don’t cut corners, don’t over-rely on AI. Stay grounded, and keep challenging yourself with every single problem.*/
#include <bits/stdc++.h>
//当遇到感觉可以写但总是卡壳的题时,不妨先冷静下来仔细思考。
//当把题目真正读懂的时候,你已经写出来了一半。
//学习他人的做法也是一种提升。
//过程是很痛苦,但唯有坚持。
//输入报错可能是数组边界问题,看下循环条件关于索引的位置有没有放反
using namespace std;
using i64 = long long;
using u64 = unsigned long long;
constexpr i64 INF = 998244353;
constexpr int N = 300005;
constexpr double IP = 2.7182818;
constexpr i64 MAXN = 1E6 + 7;
constexpr i64 MOD = 1E9 + 7;
i64 inv[1000009];
i64 f_inv[1000009];
i64 ksm(i64 x, i64 y){
i64 ans = 1;
while(y > 0){
if(y & 1){
ans = ans * x % MOD;
}
y >>= 1;
x = x * x % MOD;
}
return ans;
}
void inint(){
inv[0] = 1;
for(int i = 1;i <= 1000000; i++){
inv[i] = inv[i-1] * i % MOD;
}
f_inv[1000000] = ksm(inv[1000000], MOD-2);
for(int i = 999999; i >= 0; i--){
f_inv[i] = f_inv[i+1] * (i+1) % MOD;
}
}
i64 C(int n, int m){
if(n < m || n < 0 || m < 0) return 0;
return inv[n] * f_inv[n-m] % MOD * f_inv[m] % MOD;
}
i64 A(i64 n, i64 m){
i64 ans = 1;
for(int i = n;i >= n - m + 1; i--) ans = ans * i % MOD;
return ans;
}
template<class T>
void solve(){
string s;
std::cin >> s;
int ans = 0, cnt = 0;
//左右区间必须有一个相同,有一个不同。
for(int i = 1;i < s.size(); i++){
if(s[i] == s[i-1]) ans ++;
else cnt ++;
}
//该序列本身也是一个。
std::cout << 1LL * ans * cnt + 1 << "\n";
}
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t=1;
inint();
// cin>>t;
while(t--)
solve<int>();
return 0;
}
E
题目链接:https://ac.nowcoder.com/acm/contest/127264/E
思路:
对于1~n的每一个i,就是i个1相加,坐标的每一位距离要么为1要么为0.所以为i,就是从n位中选取i位作为1,其余都为0。总共的种类就有C(n, i) * ksm(2, n);由于会有n, v;v, n相同情况会重复计算,所以总结果/2.
代码:
/*Don’t cut corners, don’t over-rely on AI. Stay grounded, and keep challenging yourself with every single problem.*/
#include <bits/stdc++.h>
//当遇到感觉可以写但总是卡壳的题时,不妨先冷静下来仔细思考。
//当把题目真正读懂的时候,你已经写出来了一半。
//学习他人的做法也是一种提升。
//过程是很痛苦,但唯有坚持。
//输入报错可能是数组边界问题,看下循环条件关于索引的位置有没有放反
using namespace std;
using i64 = long long;
using u64 = unsigned long long;
constexpr i64 INF = 998244353;
constexpr int N = 300005;
constexpr double IP = 2.7182818;
constexpr i64 MAXN = 1E6 + 7;
constexpr i64 MOD = 1E9 + 7;
i64 inv[1000009];
i64 f_inv[1000009];
i64 ksm(i64 x, i64 y){
i64 ans = 1;
while(y > 0){
if(y & 1){
ans = ans * x % MOD;
}
y >>= 1;
x = x * x % MOD;
}
return ans;
}
void inint(){
inv[0] = 1;
for(int i = 1;i <= 1000000; i++){
inv[i] = inv[i-1] * i % MOD;
}
f_inv[1000000] = ksm(inv[1000000], MOD-2);
for(int i = 999999; i >= 0; i--){
f_inv[i] = f_inv[i+1] * (i+1) % MOD;
}
}
i64 C(int n, int m){
if(n < m || n < 0 || m < 0) return 0;
return inv[n] * f_inv[n-m] % MOD * f_inv[m] % MOD;
}
i64 A(i64 n, i64 m){
i64 ans = 1;
for(int i = n;i >= n - m + 1; i--) ans = ans * i % MOD;
return ans;
}
template<class T>
void solve(){
int n;
std::cin >> n;
for(int i = 1;i <= n; i++){
std::cout << C(n, i) * ksm(2, n-1) % MOD << " ";
}
std::cout << "\n";
}
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t=1;
inint();
// cin>>t;
while(t--)
solve<int>();
return 0;
}
F
题目链接:https://ac.nowcoder.com/acm/contest/127264/F
思路: 每条魔法路径都是一条链,他不可能为树,对于每个魔法有两种情况,要么到达没有去过的点,要么到达去过的点。
到去过的点,他所增加的期望就是点前的魔法点亮的点数*父节点的概率/当前结点的边数
否则,就前往下个节点继续分析来到之前的两种情况。
代码:
/*Don’t cut corners, don’t over-rely on AI. Stay grounded, and keep challenging yourself with every single problem.*/
#include <bits/stdc++.h>
//当遇到感觉可以写但总是卡壳的题时,不妨先冷静下来仔细思考。
//当把题目真正读懂的时候,你已经写出来了一半。
//学习他人的做法也是一种提升。
//过程是很痛苦,但唯有坚持。
//输入报错可能是数组边界问题,看下循环条件关于索引的位置有没有放反
using namespace std;
using i64 = long long;
using u64 = unsigned long long;
constexpr i64 INF = 998244353;
constexpr int N = 300005;
constexpr double IP = 2.7182818;
constexpr i64 MAXN = 1E6 + 7;
constexpr i64 MOD = 1E9 + 7;
i64 inv[1000009];
i64 f_inv[1000009];
i64 ksm(i64 x, i64 y){
i64 ans = 1;
while(y > 0){
if(y & 1){
ans = ans * x % MOD;
}
y >>= 1;
x = x * x % MOD;
}
return ans;
}
void inint(){
inv[0] = 1;
for(int i = 1;i <= 1000000; i++){
inv[i] = inv[i-1] * i % MOD;
}
f_inv[1000000] = ksm(inv[1000000], MOD-2);
for(int i = 999999; i >= 0; i--){
f_inv[i] = f_inv[i+1] * (i+1) % MOD;
}
}
i64 C(int n, int m){
if(n < m || n < 0 || m < 0) return 0;
return inv[n] * f_inv[n-m] % MOD * f_inv[m] % MOD;
}
i64 A(i64 n, i64 m){
i64 ans = 1;
for(int i = n;i >= n - m + 1; i--) ans = ans * i % MOD;
return ans;
}
template<class T>
void solve(){
int n;
std::cin >> n;
std::vector<vector<int>> adj(n+1);
for(int i = 1;i < n; i++){
int u, v;
std::cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
i64 ans = 0;
//E(x) = depth * p/k;
function<void(int, int, int, i64)> dfs = [&](int v, int parent, int step, i64 p){
p = p * ksm(adj[v].size(), MOD-2) %MOD;
for(auto &u : adj[v]){
if(u != parent){
dfs(u, v, step+1, p);
}else{
ans = (ans + 1LL * step * p % MOD) % MOD;
}
}
};
dfs(1, 1, 1, 1);
std::cout << ans << "\n";
}
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int t=1;
//inint();
// cin>>t;
while(t--)
solve<int>();
return 0;
}

查看6道真题和解析