Codeforces Round #631 (Div. 2)解题报告

题目链接

A.Dreamoon and Ranking Collection

题意:
n 1 v 给n个数,是否存在一个1-v的序列
x 其中如果某个数不存在,可以跳过x次
v 找出最大的v
题解:
用数组存一下每个数的个数
1 200 从1-200循环,如果数存在就下一个,不存在就跳过
x = = 0   & &   直到x==0~\&\&~当前数不存在

AC代码

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=2e5+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};

int a[210],b[210];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);

    int t;
    cin>>t;
    while(t--){
        int n,x,ans=0;
        cin>>n>>x;
        memset(b,0,sizeof b);
        for(int i=1;i<=n;i++)cin>>a[i],b[a[i]]=1;
        for(int i=1;i<=200;i++){
            if(!b[i]&&!x)break;
            if(!b[i])x--;
            ans=i;
        }
        cout<<ans<<endl;
    }
}


B.Dreamoon Likes Permutations

题意:
n 给一个长度为n的数组
使 是否能分成左右两部分,使得每部分成为一个序列
1 x 即包含1-x的所有数
题解:
直接计算前缀和和后缀和
m a p b r e a k 用一个map存一下是否出现重复元素,出现就break
否则用高斯公式算 如果前缀和和后缀和都满足则记录答案

AC代码

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=2e5+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};

int a[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);

    int t;
    cin>>t;
    while(t--){
        int n;
        vector<int> ans;
        map<int,int> m1,m2;
		cin>>n;
		int num=0;
		ll pre=0,sum=0;
		for(int i=1;i<=n;i++) cin>>a[i],sum+=a[i],m2[a[i]]++;
		for(ll i=1;i<n;i++){
			pre+=a[i];
			m1[a[i]]++;
			if(m1[a[i]]>1) break;
			m2[a[i]]--;
			if(m2[a[i]]==0) m2.erase(a[i]);
			if(m1.size()+m2.size()==n&&pre==(1+i)*i/2&&(sum-pre)==(1+n-i)*(n-i)/2) ans.pb(i),num++;
		}
		cout<<ans.size()<<endl;
		for(auto i:ans){
			cout<<i<<' '<<n-i<<endl;
		}
    }
}


C.Dreamoon Likes Coloring

题意:
n m L i i n个点,涂色m次,每次涂的长度为L_i,颜色为i
你选定的涂色位置必须保证整个长度都能够涂上该颜色
每个点的颜色取决于最后一次涂的颜色
确保每个颜色都存在并且每个点都有颜色
题解:
n 1 特判一下颜色不覆盖,如果不够n个点,输出-1
然后如果还没涂的长度能够大于没涂的点,就在上次涂后的下一个点涂
n 1 如果这样涂超出了n个点,就输出-1
n s u m i + 1 如果剩余还没涂的长度小于剩下的点,就在n-sum_i+1位置开始涂

AC代码

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=2e5+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};

ll l[maxn],sum[maxn],ans[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);

    int n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++)cin>>l[i];
    for(int i=m;i;--i)
        sum[i]=sum[i+1]+l[i];
    if(sum[1]<n){cout<<-1;return 0;}
    ans[1]=1;
    for(int i=2;i<=m;++i)
        ans[i]=max(ans[i-1]+1,n-sum[i]+1);
    for(int i=1;i<=m;++i)if(ans[i]+l[i]-1>n){cout<<-1;return 0;}
    for(int i=1;i<=m;++i)
        cout<<ans[i]<<' ';
    return 0;
}


D.Dreamoon Likes Sequences

题意:
d m m m 给一个数d和m,m是模数,最后答案向m取余
1 < = a 1 < a 2 < . . . . a n < = d 让你构造一个数组1<=a_1<a_2<....a_n<=d
b a b 必须存在数组b是a的异或前缀,保证b也是严格升序
题解
b 可以看出,如果b也是严格升序的话
a 必须让a的每一位数的二进制最高位大于前一位的最高位
所以就对每一二进制位循环
i 0 1 < < i 2 i i从0开始,假设最高位是1<<i,存在2^i种数
所以每次用前面的所有情况乘这个数的种类数
并且加上这个数单独存在的情况,然后加上前面所有出现的情况
O ( l o g 2 d ) d p 这样就构造出了一个O(log_2d)复杂度的dp操作
由于每次操作只和前一个有关,所以只用一个数一直维护就可以

AC代码

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=2e5+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};



int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int t;
    cin>>t;
    while(t--){
        ll d,m;
        cin>>d>>m;
        ll ans=0;
        for(int i=0;(1ll<<i)<=d;i++){
            int s=0;
            if((1ll<<(i+1))<=d)s=1<<i;
            else s=d-(1<<i)+1;
            ans=(ans+s*ans%m+s)%m;
        }
        cout<<ans<<endl;
    }

    return 0;
}

发布了12 篇原创文章 · 获赞 10 · 访问量 3099

猜你喜欢

转载自blog.csdn.net/qq_43756519/article/details/105308395