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
标程

原文地址:https://www.cnblogs.com/fisherss/p/12260611.html