2022牛客寒假算法基础集训营1 签到题7题
Posted 小哈里
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022牛客寒假算法基础集训营1 签到题7题相关的知识,希望对你有一定的参考价值。
1、L.牛牛学走路
- 恭喜你 签到成功
#include<bits/stdc++.h>
using namespace std;
int main()
int T; cin>>T;
while(T--)
int n; cin>>n;
string s; cin>>s;
int x = 0, y = 0;
double ans = 0;
for(char ch : s)
if(ch=='U')y++;
if(ch=='D')y--;
if(ch=='R')x++;
if(ch=='L')x--;
double d = sqrt(x*x+y*y);
ans = max(ans, d);
printf("%.10lf\\n",ans);
return 0;
2、E.炸鸡块君的高中回忆
- 注意 n=m=1 的特判;
- 模拟会超时,要推出公式;
- 公式不唯一,考虑让m个人先进去花掉1次,之后每轮可以进m-1个。
#include<bits/stdc++.h>
using namespace std;
int main()
int T; cin>>T;
while(T--)
int n, m; cin>>n>>m;
if(m==1)
if(n==1)cout<<"1\\n";
else cout<<"-1\\n";
else
cout<<2*((n-m)/(m-1)+((n-m)%(m-1)!=0))+1<<"\\n";
return 0;
3、J.小朋友做游戏
- 可以发现,每种里面的小朋友都是一样的,没有区别的,所以先将两种小朋友的幸福度分别按从大到小排序 记为 A 和 B 数组;那么最优的方案一定是从 A 和 B 中各选一个前缀;
- 因此可以求出两个数组的前缀和 然后枚举从 A 中选了多少人, 从B 中选的人数等于总人数减去 A 中的,利用前缀和 𝑂(1)的获得此时的总幸福度;
- 对于圆圈紧挨着的限制 其实就相当于限制闹腾小朋友最多选 n/2个, 在上面枚举的时候加入该限制即可
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 2e5+10;
int a[maxn], b[maxn];
bool cmp(int x, int y)return x>y;
int main()
int T; cin>>T;
while(T--)
int A, B, n;
cin>>A>>B>>n;
for(int i = 0; i < A; i++)cin>>a[i];
for(int i = 0; i < B; i++)cin>>b[i];
if(A<(n+1)/2)
cout<<-1<<"\\n";
continue;
LL ans = 0;
sort(a,a+A,cmp);
sort(b,b+B,cmp);
for(int i = 0; i < (n+1)/2; i++)ans += a[i];//安静的选一半先
int p = (n+1)/2, q = 0, cur = (n+1)/2;
while(cur < n) //选满n个为止
if(p>=A)ans += b[q++];
else if(q>=B)ans += a[p++];
else if(b[q]>a[p])ans += b[q++];
else ans += a[p++];
cur++;
cout<<ans<<"\\n";
return 0;
4、H.牛牛看云
- 提高对数据范围的敏感程度,注意到 𝑛≤1e6而 𝑎𝑖≤1000 可以看到 𝑎[𝑖]范围很小。
- 枚举(n,n)对儿 高达1e12,但是 (𝑖,𝑗)对儿一共也就 10^6种,也就是说极限数据下会有大量重复的值出现。
- 记 cnt[𝑖]表示 𝑖出现的次数。不同情况直接相乘表示(i,j)对出现次数,相同的情况特殊处理。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 2e5+10;
LL cnt[1010];
int main()
int n; cin>>n;
for(int i = 1; i <= n; i++)
int x; cin>>x; cnt[x]++;
LL ans = 0, times;
for(int i = 0; i <= 1000; i++)
for(int j = i; j <= 1000; j++)
if(i==j)times = (cnt[i]+cnt[i]*(cnt[i]-1)/2);
else times = cnt[i]*cnt[j];
ans += times*(LL)abs(i+j-1000);
cout<<ans<<"\\n";
return 0;
5、F.中位数切分
- 结论题
- 证明
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 2e5+10;
int main()
int T; cin>>T;
while(T--)
int n, m; cin>>n>>m;
int cnt = 0;
for(int i = 1; i <= n; i++)
int x; cin>>x; if(x>=m)cnt++;
int ans = cnt-(n-cnt);
if(ans <= 0)cout<<"-1\\n";
else cout<<ans<<"\\n";
return 0;
6、I. B站与各唱各的
推导:
- 首先注意到句子与句子之间没有办法互相影响 因此答案是一句话的期望乘以 𝑚
- 由于无法交流 每个人在唱每句时唯一的策略就是随机以 𝑝𝑖的概率决定唱或不唱这一句
- 又由于 𝑛个人之间没有区别 所以不同人的概率一定是相等的 记为 𝑝
- 因此 唱失败的概率是 𝑝^𝑛+(1−𝑝)^𝑛 求其最小值得 𝑝=1/2 进而计算可以得到最终答案;
结论:
- 答案即为𝑚×(2^𝑛−2)/(2^𝑛),除法需要用逆元
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 2e5+10;
const int mod = 1e9+7;
LL pows(LL a, LL x, LL p)if(x==0)return 1; LL t = pows(a, x>>1,p);if(x%2==0)return t*t%p;return t*t%p*a%p;
void EXGCD(int a, int b, int &d, int &x, int & y, int MOD) if (b==0) d = a; x = 1; y = 0; else EXGCD(b, a % b, d, y, x, MOD); y -= x * (a / b);
int inv(int a, int MOD) int d=0, x=0, y=0; EXGCD(a, MOD, d, x, y, MOD); return d == 1 ? (x + MOD) % MOD : -1;
int main()
int T; cin>>T;
while(T--)
int n, m; cin>>n>>m;
LL ans = m*(pows(2,n,mod)-2)%mod*inv(pows(2,n,mod),mod)%mod;
cout<<ans<<'\\n';
return 0;
7、D.牛牛做数论
- 结论
问题一的答案为 2 、 2 × 3 、 2 × 3 × 5 、 2 × 3 × 5 × 7… 这些前若干个素数的积中,最大的且不超过 n 的那一个,如 n=233 ,则答案为2 × 3 × 5 × 7=210 。
问题二的答案为 [2,n] 中最大的素数。 - 证明
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int isprime(LL x)
for(LL i = 2; i*i <= x; i++)
if(x%i==0)return 0;
return 1;
int main()
int T; cin>>T;
while(T--)
int n; cin>>n;
if(n==1)cout<<"-1\\n"; continue;
LL a = 1, b;
for(LL i = 2; i*a <= n; i++)
if(isprime(i))a*=i;
for(b = n; ;b--)
if(isprime(b))break;
cout<<a<<" "<<b<<"\\n";
return 0;
以上是关于2022牛客寒假算法基础集训营1 签到题7题的主要内容,如果未能解决你的问题,请参考以下文章