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

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

原文地址:https://www.cnblogs.com/Tianwell/p/11521529.html