zoukankan      html  css  js  c++  java
  • Codeforces Round #584 (div.1+div.2)(补题)

    CF题解博客:https://codeforces.com/blog/entry/69791?tdsourcetag=s_pcqq_aiomsg

    补题中...

    A. Paint the Numbers

    题意:

    给一个序列,选出其中某几个数,满足整个序列可以被选择的某个数整除。求最少选择的数个数。

    思路:

    暴力枚举所有元素组合(题中值比较小)。

    code:

    #include <bits/stdc++.h>
    using namespace std;
     
    typedef long long ll;
    const int mod = 1e9+7;
    const int maxn = 108;
     
    int a[maxn];
    int cnt;
    bool vis[maxn];
    
    bitset<101> bs;
     
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1; i<=n; i++){
            scanf("%d",a+i);
        }
        sort(a+1,a+1+n);
        int ans=0;
        int flag=0;
        bs.reset();
        for(int i=1; i<=n; i++){
            flag=0;
            for(int j=i; j<=n; j++){
                if(a[j]%a[i]==0 && !bs[j]){
                    bs[j] = 1;
                    flag = 1;
                }
            }
            if(flag){
                ans++;
            }
            if(bs.count()==n){
                printf("%d
    ", ans);
                return 0;
            }
        }
        printf("%d
    ", ans);
    }
    View Code

    B. Koala and Lights

    题意:

    给你 N 灯泡的初始状态(开或者关),然后对于每一个灯泡,给出两个值 a,b; a 代表快关状态切换的周期,b代表第一次切换的时刻。问在某一时刻,能够同时亮的灯泡数目,最多有多少。

    思路:

    暴力:枚举1e5所有时刻,然后统计最大值。

    code:

    #include <bits/stdc++.h>
    using namespace std;
     
    typedef long long ll;
    const int mod = 1e9+7;
    const int maxn = 108;
     
    char s[maxn]; 
    int a[maxn],b[maxn],c[maxn];
    bitset<maxn> bs;
     
    int main(){
        int n;
        scanf("%d",&n);
        scanf("%s",s+1);
        bs.reset();
        for(int i=1; i<=n; i++){
            bs[i] = s[i]-'0';
        }
        for(int i=1; i<=n; i++){
            scanf("%d%d",a+i,b+i);
        }
        int ans=0;
        for(int j=0; j<=30000; j++){
            for(int i=1; i<=n; i++){
                if( j>=b[i] && ((j-b[i])%a[i] )==0 )  {
                    bs[i] = (int)bs[i]^1;
                }
            }
            ans = max(ans,(int)bs.count());
        }
        printf("%d
    ", ans);
    }
    View Code

    C. Paint the Digits

    题意:

    给出一个序列,然后从中选择出两个子序列,保证 两个子序列本身 (非递减),以及保证 最后选择出的 序列 12 也呈(非递减)排列

    思路:

    非递减排列,子序列。很容易就想到单调栈。所以我们就先跑一边单调队列,找出所有符合条件的1。但同时还要对队列1进行处理,即找到2中的第一个元素,把所有队列1中大于2的第一个元素全部出栈,

    这样就可以满足 12 也呈 非递减排列。而对于无解的情况即是,判断第一次处理好1之后剩下的序列是否呈 非递减即可。

    code:

    #include <cstdio>
    #include <queue>
    #include <iostream>
    #include <algorithm>
    #include <stack>
    #include <string>
    #include <cstring> 
    using namespace std;
    const int maxn  =2e5+7;
    const int inf = 0x3f3f3f3f;
    char arr[maxn];
    stack<int>a;
    int top;
    struct node{
        int val;
        int cur;
    }s[maxn]; 
     
    void init(){
        top = 0;
        s[0].val = -1; s[0].cur = -1;
        while(!a.empty()) a.pop();        
    } 
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            int n,m;
            scanf("%d",&n);
            scanf("%s",arr); 
            init();
            for(int i=0;i<n;i++){
                while(s[top].val>arr[i]-'0'){
                    top--;
                }
                s[++top].val = arr[i]-'0';
                s[top].cur = i;
            }
            int first=-1;//最后最小位置 
            int cu=1;
            for(int i =0;i<n;i++){
                if(s[cu].cur==i) cu++;
                else{
                    first = i;
                    break;
                } 
            }
            while(s[top].val>arr[first]-'0'&&first!=-1){
                top--;
            }
            cu = 1;
            for(int i =0;i<n;i++){
                if(s[cu].cur==i&&cu<=top) {
                    //找到第一个最小位置 
                    cu++;
                }else a.push(arr[i]-'0');
            }
            int flag = 0; 
            if(!a.empty()){
                int now = a.top(); a.pop();
                int len = a.size();
                for(int i=0;i<len;i++){
                    int tmp = a.top();
                    a.pop();
                    if(now<tmp) {
                        flag = 1; break;
                    }
                    now = tmp;
                }
            }
            if(flag){
                puts("-");
            }else{
                cu = 1;
                for(int i =0;i<n;i++){
                    if(i==s[cu].cur&&cu<=top){
                        printf("1");
                        cu++;
                    }else printf("2");
                }
                puts("");
            }
        }
    }
    View Code

     然后看了大佬的题解,实际上可以使用更加简单的方法。

    记录一个备份序列,然后将其排序。再对原序列与排序后的序列对比,(这样就可以直接把原序列中满足条件的位置找出来,作为集合1中的值),然后再跑一遍,作为集合2中的值。如果值没有取完,则输出'-', 否则就可以直接输出 ans.

    #include <iostream>
    #include <string>
    #include <algorithm>
    #define IOS ios::sync_with_stdio(0); cin.tie(0);
    using namespace std;
    
    string s,ss,ans;
    int main(){
        IOS
        int T;
        cin>>T;
        while(T--){
            cin>>n>>s;
            ss = s,ans = s;
            sort(ss.begin(),ss.end());
            int k=0;
            for(int i=0;i<n;i++){
                if(s[i]==ss[k]){
                    s[i] = '#';
                    k++;
                    ans[i] = '1';
                }
            }
            for(int i=0;i<n;i++){
                if(s[i]==ss[k]){
                    s[i] = '#';
                    k++;
                    ans[i] = '2';
                }
            }
            if(k==n) cout<<ans<<endl;
            else cout<<'-'<<endl;
        }
    }
    View Code

    D. Cow and Snacks

    题解连接(对这道题单独写了下)

  • 相关阅读:
    即将到来的Android N,将具备这些新特性
    刚挣钱的程序猿同学该怎样花钱?
    Swift函数
    MVC
    css3硬件加速
    node+mongoDB+express项目需求解释
    柯里化
    web安全
    缓存机制详解
    nodejs --- crypto实现加密(转)
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11521529.html
Copyright © 2011-2022 走看看