牛客小白月赛

记录

  1. 树状数组:
    冷静
  2. 类最长上升子序列
    糟糕的打谱员
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int dp[100010];
int mx[3][12];
int a[100010],b[100010];

int main()
{
    
    
    int t;
    scanf("%d",&t);
    while(t--){
    
    
        
        memset(dp, 0, sizeof(dp));
        memset(mx, 0, sizeof(mx));        
        int n;
        scanf("%d",&n);
        
        for(int i=1;i<=n;i++){
    
    
            scanf("%d%d",&a[i],&b[i]);
        }
        
        int ans = 0;
        for(int i=1;i<=n;i++){
    
    
            dp[i] = 1;
                
            for(int j=1;j<=10;j++){
    
    
                if(j==b[i])    continue;
                
                dp[i] = max(dp[i],dp[mx[!a[i]][j]]+1);
            }
            mx[a[i]][b[i]] = i;
            ans = max(ans,dp[i]);
        }
        cout << ans << endl;
    }
    
    return 0;
}
  1. 又一数区间问题(暴力)
    又一数区间问题
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long ll;

int ne[100010];

int main()
{
    
    
    int n;
    scanf("%d",&n);
    string s;
    cin >> s;
    s = " " + s;
    
    int pos = n+1;
    ne[n+1] = 1e9;
    for(int i=n;i>=1;i--){
    
    
        ne[i] = pos;
        
        if(s[i]-'0' != 1){
    
    
//             ne[cnt++] = i;     // 记录非1的位置不如记录a[i]下一个非1的位置.
            pos = i;
        }
    }
    
    ll ans = 0;
//     ans = n-cnt;
    for(int i=1;i<=n;i++){
    
    
        ll sum = 1;
        for(int j=i;j<=n+1&&sum<=n;j=ne[j]){
    
    
            sum *= (s[j]-'0');
            if(sum==(j-i+1)){
    
    
                ans++;
            }
            if(j-i+1<sum&&ne[j]-i>=sum) ans++;
        }
    }
    
    cout << ans << endl;
    
    return 0;
}
  1. 定义并计算期望.
    一个经典概率问题
//计算每条弦中点(即题面中的点P)到圆心的距离的期望。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int main()
{
    
    
    long double sum = 0;
    int n; cin >> n;
    for(int i= 1; i <= n; i++){
    
    
        long double d;cin >> d;
        sum += sqrt(1.0-d*d/4);
    }
    sum/=n;
    if(sum > 0.47 && sum < 0.53){
    
    
        cout << "L\n";
    }else cout << "B\n";
    return 0;
}
  1. 构造序列问题
    又一构造子序列
#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

typedef long long ll;

ll getSum(ll x){
    
    
    return x*x+3*x+2;
}

int main()
{
    
    
    int t;
    scanf("%d",&t);
    while(t--){
    
    
        ll n;
        scanf("%d",&n);
        
        if(n==1){
    
    
            cout << "5\nyycnb" << endl;
            continue;
        }
        
        ll x,sum;
        for(ll i=0;;i++){
    
    
            if(getSum(i+1)>n){
    
    
                sum = getSum(i);
                x = i;
                break;
            }
        }
        ll z = n - sum;
        printf("%lld\n",(4+z+x));
        printf("yy");
        for(int i=0;i<z;i++){
    
    
            printf("c");
        }
        for(int i=0;i<x;i++){
    
    
            printf("y");
        }
        printf("cc\n");
    }
    
    return 0;
}
  1. 思维
    进击的图灵机
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>

using namespace std;

typedef pair<int,int> PII;
map<PII,vector<int> > mp;
PII p[200010];

int main()
{
    
    
    int n,m;
    scanf("%d%d",&n,&m);
    string s;
    cin >> s;
    s = " " + s;
    int x = 0, y = 0;
    for(int i=1;i<=n;i++){
    
    
        p[i] = make_pair(x,y);
        if(s[i]=='U'){
    
    
            y++;
        }else if(s[i]=='D'){
    
    
            y--;
        }else if(s[i]=='R'){
    
    
            x++;
        }else{
    
    
            x--;
        }
        
        mp[make_pair(x,y)].push_back(i);
    }
    
    int l,r;
    while(m--){
    
    
        scanf("%d%d",&l,&r);
        PII x = p[l];
        int ans=upper_bound(mp[x].begin(),mp[x].end(),r)-lower_bound(mp[x].begin(),mp[x].end(),l);
        printf("%d\n",ans);
    }
    
    return 0;
}
  1. 比那名居的桃子
// 1.a数组连续k个数和最大
// 2.如果1有多个,b数组这k个数和应最小
// 如果1.2都不满足,尽可能早

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

//没开longlong:裂开.

using namespace std;
typedef long long ll;

ll a[100010],b[100010];

int main()
{
    
    
    ll n,k;
    scanf("%lld%lld",&n,&k);
    for(int i=1;i<=n;i++)    scanf("%lld",&a[i]);
    for(int i=1;i<=n;i++)    scanf("%lld",&b[i]);
    
    ll ans = 1;
    
//     int x = n-k+1;
    ll happy = 0,unhappy = 0;
//     int cnt = 0;
    if(k>=n){
    
    
        cout << "1\n";
    }else{
    
    
        for(int i=1;i<=k;i++)    happy += a[i],unhappy += b[i];
        ll ma = happy,ma2 = unhappy;
        for(int i=k+1;i<=n;i++){
    
    
            happy = happy + a[i] - a[i-k];
            unhappy = unhappy + b[i] - b[i-k];
            
            if((happy>ma) || (happy==ma && unhappy<ma2)){
    
    
                ma = happy;
                ma2 = unhappy;
                ans = i-k+1;
            }
        }
        
        cout << ans << endl;
    }

    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_50435987/article/details/121015772