zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 65 (Rated for Div. 2) A-F解题报告

    在这里插入图片描述
    这场被B题坑了一小时,其他做起来都是一眼题。

    A:正常模拟就好
    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define forn(i,n) for(int i=0;i<n;i++)
    #define for1(i,n) for(int i=1;i<=n;i++)
    #define ll long long
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    
    
    int main(){
        IO;
        int t;cin>>t;
        while(t--){
            int n;string s;
            cin>>n>>s;
            if(n<11){
                cout<<"NO"<<'
    ';
                continue;
            }
            int x = n-11,flag = -1;
            forn(i,n){
                if(s[i]=='8'){
                    flag = i;
                    break;
                }
            }
            if(flag==-1){
                cout<<"NO"<<'
    ';
                continue;
            }
            if(flag>x){
                cout<<"NO"<<'
    ';
                continue;
            }
            cout<<"YES"<<'
    ';
        }
    
    
        return 0;
    }
    

    B题:
    这题放两个思路

    1. 思路一:询问12 23确定1 2 3的值;询问45 56确定4 5 6的值
    2. 思路二:取六个数的全排列符合输出
      代码一:
    #include <bits/stdc++.h>
    using namespace std;
    #define forn(i,n) for(int i=0;i<n;i++)
    #define for1(i,n) for(int i=1;i<=n;i++)
    #define ll long long
    #define IO ios::sync_with_stdio(false);cin.tie(0)
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    
    vector<int>ans,cnt;
    int z[] = {32,60,64,92,168,120,128,184,336,240,345,630,368,672,966};
    int x[] = {4,4,4,4,4,8,8,8,8,15,15,15,16,16,23};
    int y[] = {8,15,16,23,42,15,16,23,42,16,23,42,23,42,42};
    void get(int t){
        forn(i,15){
            if(t==z[i]){
                cnt.push_back(x[i]);
                cnt.push_back(y[i]);
            }
        }
    }
    
    int vis[100];
    
    int main(){
        int num[6]={4, 8, 15, 16, 23, 42};
        int a;
        printf("? 1 2
    ");
        //cout<<"? 1 2"<<'
    ';
        fflush(stdout);
        cin>>a;
        get(a);
        printf("? 2 3
    ");
        //cout<<"? 2 3"<<'
    ';
        fflush(stdout);
        cin>>a;
        get(a);
    
        forn(i,4){
            vis[cnt[i]]++;
        }
        forn(i,4){
            if(vis[cnt[i]]==1){
                ans.push_back(cnt[i]);
                break;
            }
        }
        forn(i,4){
            if(vis[cnt[i]]==2){
                ans.push_back(cnt[i]);
                break;
            }
        }
        for(int i=3;i>=0;i--){
            if(vis[cnt[i]]==1){
                ans.push_back(cnt[i]);
                break;
            }
        }
        cnt.clear();
        printf("? 4 5
    ");
        //cout<<"? 4 5"<<'
    ';
        fflush(stdout);
        cin>>a;
        get(a);
        printf("? 5 6
    ");
        //cout<<"? 5 6"<<'
    ';
        fflush(stdout);
        cin>>a;
        get(a);
        cerr<<a<<'
    ';
        forn(i,4){
            vis[cnt[i]]++;
        }
        forn(i,4){
            if(vis[cnt[i]]==1){
                ans.push_back(cnt[i]);
                break;
            }
        }
        forn(i,4){
            if(vis[cnt[i]]==2){
                ans.push_back(cnt[i]);
                break;
            }
        }
        for(int i=3;i>=0;i--){
            if(vis[cnt[i]]==1){
                ans.push_back(cnt[i]);
                break;
            }
        }
    
    
        printf("! ");
        forn(i,6){
            printf("%d ",ans[i]);
        }
        printf("
    ");
    
        return 0;
    }
    

    代码二:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define forn(i,n) for(int i=0;i<n;i++)
    #define for1(i,n) for(int i=1;i<=n;i++)
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    
    int main(){
        vector<int>v = {4, 8, 15, 16, 23, 42},a;
        cout<<"? 1 2"<<'
    ';
        int x;cin>>x;a.push_back(x);
        cout<<"? 2 3"<<'
    ';
        cin>>x;a.push_back(x);
        cout<<"? 3 4"<<'
    ';
        cin>>x;a.push_back(x);
        cout<<"? 4 5"<<'
    ';
        cin>>x;a.push_back(x);
        do{
            if(v[0]*v[1]!=a[0]) continue;
            if(v[1]*v[2]!=a[1]) continue;
            if(v[2]*v[3]!=a[2]) continue;
            if(v[3]*v[4]!=a[3]) continue;
            cout<<'!';
            for(auto x:v) cout<<' '<<x;
            return cout<<'
    ',0;
        }while(next_permutation(v.begin(),v.end())); 
    }
    

    C题:裸的并查集 比赛时找不到板子我手敲都5分钟写完

    #include <bits/stdc++.h>
    using namespace std;
    #define forn(i,n) for(int i=0;i<n;i++)
    #define for1(i,n) for(int i=1;i<=n;i++)
    #define ll long long
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const int maxn  = 5e5+5;
    
    int par[maxn],rankk[maxn],a[maxn];
    
    void init(int n){
        for1(i,n){
            rankk[i] = 1;
            par[i] = i;
        }
    }
    
    int find(int x){
        return par[x]==x?x:par[x] = find(par[x]);
    }
    
    void unit(int x,int y){
        x = find(x),y = find(y);
        if(x==y) return;
        if(rankk[x]>rankk[y]) swap(x,y);
        par[x] = y;
        rankk[y] += rankk[x];
    }
    
    int main(){
        IO;
        int n,m;cin>>n>>m;
        init(n);    
        forn(i,m){
            int x;cin>>x;
            forn(i,x) cin>>a[i];
            for1(i,x-1) unit(a[i],a[i-1]);
        }
        for1(i,n) cout<<rankk[find(i)]<<' ';
        cout<<'
    ';
    
        return 0;
    }
    

    D题不难想出 左括号按01 右括号按01顺下去
    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define forn(i,n) for(int i=0;i<n;i++)
    #define for1(i,n) for(int i=1;i<=n;i++)
    #define ll long long
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const int maxn = 2e5+5;
    
    int ans[maxn];
    
    int main(){
        IO;
        int n;string s;cin>>n>>s;
        int a =0,b=0;
        forn(i,n){
            if(s[i]=='('){
                a++;
                if(a&1) ans[i] = 0;
                else ans[i] = 1;
            }
            else{
                b++;
                if(b&1) ans[i] = 0;
                else ans[i] = 1;
            }
        }
        forn(i,n) cout<<ans[i];
        cout<<'
    ';
        return 0;
    }
    

    E题 双指针
    n个数 删除[1,J]满足数组不递减 肯定满足删除[1,j+1] [1,j+2]…[1,n]都满足不递减
    那我们先以左端点为1,找到最小的右端点的值j,此时ans+=k-j+1
    然后我们来看看[2,j]可以吗 不可以就看看[2,j+1] [2,j+2]…知道找到一个新的最小j,此时ans+=k-j+1
    以此类推我们滑动双指针的复杂度为O(4*N)

    因为n为1e6 每次判断必须是O1或者Ologn,这边就是这个思路的难点了
    这里我是O1的,存了4个数组

    1. l数组记录大小为i的数第一次出现的位置
    2. r数组记录大小为i的数最后一次出现的位置
    3. L数组记录区间(i~n)大小的数第一次出现的位置
    4. R数组记录区间(1-i)大小的数最后一次出现的位置
      这些预处理也都是On的处理

    判断以1为左端点时,我只要判断L[j]是否小于r[j-1]
    定左端点时:
    我要确保左端点前的L[i-1](左端点前所有的数最后一次出现的位置)
    小于R[j+1](右端点后的所有的数第一次出现的位置)

    再剩下的就是细节调整了
    因为我R初始化了正无穷,所以j最大为k
    当j=k时 ans+=k-j+1,如果此时不符合条件就不能继续算下去了

    然后我们发现如果左端点前的R[i-2](左端点变化前的所有的数最后一次出现的位置)
    大于l[i-1](更新的这个值)那么此时操作已经无效可以终止了break。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define forn(i,n) for(int i=0;i<n;i++)
    #define for1(i,n) for(int i=1;i<=n;i++)
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    const int maxn = 1e6+5;
    const int inf = 0x3f3f3f3f;
    
    int a[maxn],l[maxn],r[maxn],L[maxn],R[maxn];
    
    int main(){
        IO;
        int n,k;cin>>n>>k;
        memset(l,inf,sizeof(l));
        memset(L,inf,sizeof(L));
        memset(r,-1,sizeof(r));
        memset(R,-1,sizeof(R));
        for1(i,n){
            cin>>a[i];
            l[a[i]] = min(i,l[a[i]]);
            r[a[i]] = i; 
        }
        for1(i,k) R[i] = max(r[i],R[i-1]);
        for(int i=k;i>=1;i--) L[i] = min(l[i],L[i+1]);
        int j = k;
        while(j>1&&L[j+1]>=r[j]) j--;
        ll ans = 0;
        ans+=k-j+1;
        for(int i=2;i<=k;i++){
            if(R[i-2]>l[i-1]) break;
            while(j<i||R[i-1]>L[j+1]) j++;
            ans+=k-j+1;
        }
        cout<<ans<<'
    ';
        return 0;
    }
    

    F题留坑

    人一我百,人十我万。
  • 相关阅读:
    kill process
    USB development guide
    MMC device
    memtester
    printf()格式化输出详解
    C语言动态内存分配
    归并排序C语言
    c 文件操作
    数据包分析
    C语言文件操作函数大全
  • 原文地址:https://www.cnblogs.com/AlexPanda/p/12520332.html
Copyright © 2011-2022 走看看