2022/1/13

div3 797

A

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int n;
        cin >> n;
        int h1 = n / 3 + ((n % 3) == 2 ? 1 : 0), h3 = n / 3 - 1, h2 = n / 3 + 1 + ((n % 3) > 0 ? 1 : 0);
        cout << h1 << " " << h2 << " " << h3 << endl;
    }
}

B

#include<bits/stdc++.h> 
using namespace std;
#define ll long long 
const int maxn=2e5+7;
int a[maxn],b[maxn];
#define sc scanf
int main() {
    int t;cin>>t;
    while(t--){
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)sc("%d",&a[i]);
        for(int i=1;i<=n;i++)sc("%d",&b[i]);
        int c=INT_MAX;
        for(int i=1;i<=n;i++){
            if(b[i]!=0)
            {
                c=a[i]-b[i];continue;
            }
             
        }
        
        if(c<0){
            cout<<"NO"<<endl;
            continue;
        }
        else if(c==INT_MAX){
            cout<<"YES"<<endl;
            continue;
        }
        int f=1;
        for(int i=1;i<=n;i++){
            if(b[i]==0){
                if(a[i]<=c)continue;
            }
            if(a[i]-b[i]!=c){
                f=0;break;
            }
        }
        if(f)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}

C

#include<iostream>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
const int N = 2e5 + 10;
typedef pair<int, int> PII;
int ans[N];
PII a[N];
void solve()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i].first;
    }
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i].second;
    }
    int top = 0;
    for (int i = 1; i <= n; i++)
    {
        if (a[i].first >= top)
        {
            ans[i] = a[i].second - a[i].first;
            top = max(top, a[i].second);
        }
        else
        {
            //cout << top << " " << i << " i " << a[i].second << endl;
            if (top >= a[i].second) ans[i] = 0;
            else
            {
                
                ans[i] = a[i].second - top;
                top = a[i].second;
            }
        }
        
    }
    for (int i = 1; i <= n; i++) cout << ans[i] << " ";
    puts("");
}
signed main()
{
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
}

D

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 2e5 + 10;
int vis[N];
void solve()
{
    memset(vis, 0, sizeof vis);
    int n, k;
    cin >> n >> k;
    string str;
    cin >> str;
    str = 's' + str;
    for (int i = 1; i <= n; i++)
    {
        vis[i] = vis[i - 1];
        if (str[i] == 'B') vis[i]++;
        
    }
    int cnt = 0;
    for (int i = k; i <= n; i++)
    {
        cnt = max(cnt, vis[i] - vis[i - k]);
        //cout << vis[i] << " i " << i << endl;
    }
    cout << k - cnt << endl;
}
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
}

E

#include<iostream>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
const int N = 2e5 + 10;
int a[N];
void solve()
{
    int n, k;
    int ans = 0;
    //memset(vis, 0, sizeof vis);
    cin >> n >> k;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        ans += a[i] / k;
        a[i] %= k;
    }
    sort(a + 1, a + 1 + n);
    int l = 1, r = n;
    while (l < r)
    {
        if (a[l] + a[r] >= k)
        {
            ans++; l++;
            r--;
        }
        else l++;
    }
    
    

    cout << ans << endl;
}
signed main()
{
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
}

F

用到了置换环,每个置换环的最小循环节的最小公倍数就是答案

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#define int long long
using namespace std;
const int N = 1000;
int vis[N], p[N];
int gcd(int a, int b)
{
    return b ? gcd(b, a % b) : a;
}
void solve()
{
    memset(vis, 0, sizeof vis);
    int n;
    string str;
    cin >> n >> str;
    str = 's' + str;
    int ans = 1;
    for (int i = 1; i <= n; i++) cin >> p[i];
    for (int i = 1; i <= n; i++)
    {
        if (vis[i]) continue;
        vis[i] = 1;
        vector<char> s;
        s.push_back(str[i]);
        int x = i;
        while (vis[p[x]] == 0)
        {
            x = p[x];
            vis[x] = 1;
            s.push_back(str[x]);
        }
        int len = s.size();
        for (int l = 1; l <= len; l++)
        {
            
            if (len % l == 0)
            {
                bool check = 1;
                for (int j = l; j < len; j++)
                {
                    if (s[j] != s[j - l])
                    {
                        check = 0;
                        break;
                    }
                }
                if (check)
                {
                    ans = ans * l / gcd(ans, l);
                    break;
                }
            }
        }
        
    }
    cout << ans << endl;

}
signed main()
{
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
}

G

维护了一个最长严格下降子序列,每次操作后都在原序列改动,前驱后驱的具体实现说实话还是挺陌生的

插入后如果是一个新数则需要先和前驱比较,判断是否需要删去本身,再和后驱比较小的全部删掉,可以暴力遍历序列。


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

#include<map>
#define int long long
using namespace std;
const int N = 1e5 + 10;
int arr[N];
int n, m;
map<int, int> mp;
void add(int i, int num)
{
    mp[i] = num;
    auto pos = mp.find(i);
    if (pos != mp.begin() && num >= prev(pos)->second)
    {
        mp.erase(pos);
        return;
    }
    while (next(pos) != mp.end() && num <= next(pos)->second)
    {
        mp.erase(next(pos));
    }
}
void solve()
{
    mp.clear();
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> arr[i];
        add(i, arr[i]);
    }
    while (m--)
    {
        int a, b;
        cin >> a >> b;
        arr[a] -= b;
        add(a, arr[a]);
        cout << mp.size() << " ";
    }
    puts("");

}
signed main()
{
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值