2020牛客寒假算法基础集训营1
牛客题解:https://www.nowcoder.com/discuss/364600
是不是改时间了,明明记的是下午2点开始,结果,,
A 思维,计数
队友做的
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
int main(){
ll n,m;
cin>>n>>m;
ll ans = 0;
if(n == 2 && m == 2){
cout<<0;
return 0;
}
else{
if(n>2){
ll tn = n - 2;
ans =(ans+ ( ( (tn*n)%mod)*(2*m-2) )%mod )%mod;
}
if(m>2){
ll tm = m - 2;
ans = (ans+( ( (tm*m)%mod)*(2*n-2) )%mod )%mod;
}
if(n>3){
ll tn = n - 1;
ans = (ans + (tn * (n -2)%mod )*(2*m - 4)%mod ) %mod;
}
if(m>3){
ll tm = m - 1;
ans = (ans + (tm * (m -2)%mod )*(2*n - 4)%mod ) %mod;
}
}
cout<<ans;
return 0;
}
B 简单题
简单题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
double n,x,a,b;
double ans;
int main(){
cin>>n>>x>>a>>b;
ans = (x*a + (100-x)*b)*n/100;
printf("%.2lf",ans);
return 0;
}
C 计算几何+双指针
计算几何+双指针,待补
D 简单题
简单题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n;
int main(){
cin>>n;
ll ans = (n+1)*n/2;
for(int i=1;i<=n-1;i++){
ll d;
cin>>d;
ans -= d;
}
cout<<ans;
return 0;
}
E 数论 唯一分解定理
求因子个数,唯一分解定理
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll solve(ll n){
ll sum=1;
for(ll i=2;i*i<=n;i++){
int cnt=0;
while(n%i==0){
n/=i;
cnt++;
}
sum*=(cnt+1);
}
if(n>1)
sum*=2;
return sum;
}
int main() {
ll x;
cin>>x;
int cnt = 1;
while(1){
int cur = solve(x);
if(cur == 2){
cout<<cnt;
break;
}
cnt++;
x = cur;
}
return 0;
}
F 并查集缩点 + 前缀和
方法一:并查集缩点 + 前缀和优化
队友AC地址
方法二:dfs做法,具体就是树上做了一些动作
校友AC地址
G 字符串 双指针
双指针
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string s;
int n,k;
int cnt[27];
bool solve(){
for(int i=0;i<26;i++)
if(cnt[i] >= k)
return true;
return false;
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>k;
cin>>s;
int ans = 0x3f3f3f3f;
int len = s.length();
int j = 1;
cnt[s[0]-'a']++;
if(len >= 1) cnt[s[1]-'a']++;
for(int i=0;i<len;i++){
while(j < len-1 && !solve()){
j++;
cnt[s[j] - 'a']++;
}
if(solve()) {
if(j>=len){
ans = min(ans,j-1-i+1);
}else{
ans = min(ans,j-i+1);
}
}
cnt[s[i] - 'a']--;
}
if(ans == 0x3f3f3f3f) cout<<"-1";
else cout<<ans;
return 0;
}
H 字符串 双指针
两遍双指针
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2000001;
int n,k;
string s;
int cnt;
int ans = -0x3f3f3f3f;
int vis[maxn];
int main(){
cin>>n>>k;
cin>>s;
int len = s.length();
if(len == 1){
cout<<1;
return 0;
}
int i = 0;
int j = 1;
if(s[0] == '0') cnt++;
for(i=0;i<len;i++){
while(j <= len-1 && (s[j] == '1' || (cnt<=k))) {
if(s[j] == '0' && !vis[j]) {
vis[j] = 1;
cnt++;
}
if(cnt > k) break;
ans = max(ans,j-i+1);
j++;
}
if(s[i] == '0') cnt--;
}
cnt = 0;
i = 0,j = 1;
if(s[0] == '1') cnt++;
for(int p = 0;p<len;p++) vis[p] = 0;
for(i=0;i<len;i++){
while(j <= len-1 && (s[j] == '0' || (cnt <= k))){
if(s[j] == '1' && !vis[j]) {
vis[j] = 1;
cnt++;
}
if(cnt > k) break;
ans = max(ans,j-i+1);
j++;
}
if(s[i] == '1') cnt--;
}
cout<<ans;
return 0;
}
I 字符串 dp
队友dp
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<utility>
#include<cstring>
#include<string>
#include<vector>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int maxn=3e5+10;
ll f[maxn];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
string s,t;
ll n, a, b, c;
cin >> n >> a>> b >> c;
s.resize(1);
s[0] = 'w';
cin >> t;
s+=t;
for (int i=1; i<=n; i++) {
if (i >= 4 && s.substr(i - 3, 4) == "nico")
f[i] = max(f[i], f[i - 3] + a);
if (i >= 6 && s.substr(i - 5, 6) == "niconi")
f[i] = max(f[i], f[i - 5] + b);
if (i >= 10 && s.substr(i - 9, 10) == "niconiconi")
f[i] = max(f[i], f[i - 9] + c);
f[i] = max(f[i], f[i - 1]);
}
cout << f[n] << endl;
return 0;
}
J 数论 矩阵快速幂
数论,矩阵快速幂
可以先用费马小对b降幂
a的b次幂,这里的b每一项构成了斐波那契数列,矩阵快速幂求斐波那契数列的n项,再乘以x*y
标程