zoukankan      html  css  js  c++  java
  • Codeforces Round #547题解

    A题

    先除再计算即可

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    typedef pair<int,int> plll;
    const int N=3e5+10;
    const int inf=0x3f3f3f3f;
    int main(){
        ios::sync_with_stdio(false);
        int n,m;
        cin>>n>>m;
        int flag=0;
        int cnt=0;
        if(m%n){
            cout<<-1<<endl;
            return 0;
        }
        n=m/n;
        while(n%2==0){
            n/=2;
            cnt++;
        }
        while(n%3==0){
            n/=3;
            cnt++;
        }
        if(n==1){
            cout<<cnt<<endl;
        }
        else{
            cout<<-1<<endl;
        }
        return 0;
    }
    View Code

    B题

    因为保证存在一个,因此直接扩大一倍,这样答案肯定在这之间

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    typedef pair<int,int> plll;
    const int N=4e5+10;
    const int inf=0x3f3f3f3f;
    int a[N];
    int main(){
        ios::sync_with_stdio(false);
        int n;
        cin>>n;
        int i;
        for(i=1;i<=n;i++)
            cin>>a[i];
        for(i=n+1;i<=2*n;i++){
            a[i]=a[i-n];
        }
        int ans=0;
        int cnt=0;
        for(i=1;i<=2*n;i++){
            if(a[i]==0){
                ans=max(ans,cnt);
                cnt=0;
            }
            else{
                cnt++;
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

    C题

    因为排列是每个都不同,因此用前缀和计算出最大的那个,那个就是n

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    typedef pair<int,int> plll;
    const int N=4e5+10;
    const int inf=0x3f3f3f3f;
    int p[N];
    ll sum;
    int ans[N],st[N];
    int main(){
        ios::sync_with_stdio(false);
        int n;
        cin>>n;
        int i;
        int pos=1;
        int mx=0;
        for(i=2;i<=n;i++){
            cin>>p[i];
            sum+=p[i];
            if(sum>mx){
                sum=mx;
                pos=i;
            }
        }
        ans[pos]=n;
        st[n]=1;
        for(i=pos-1;i>=1;i--){
            ans[i]=ans[i+1]-p[i+1];
            if(ans[i]<=0||ans[i]>n||st[ans[i]]){
                cout<<-1<<endl;
                return 0;
            }
            st[ans[i]]=1;
        }
        for(i=pos+1;i<=n;i++){
            ans[i]=ans[i-1]+p[i];
            if(ans[i]<=0||ans[i]>n||st[ans[i]]){
                cout<<-1<<endl;
                return 0;
            }
            st[ans[i]]=1;
        }
        for(i=1;i<=n;i++){
            cout<<ans[i]<<" ";
        }
        cout<<endl;
        return 0;
    }
    View Code

    D题

    发现每一位是独立的,因此用每一位进行匹配,之后再用多余的?进行匹配

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    typedef pair<int,int> plll;
    const int N=4e5+10;
    const int inf=0x3f3f3f3f;
    int a[N];
    int b[N];
    vector<int> num1[27];
    vector<int> num2[27];
    vector<int> res1,res2;
    vector<pll> ans;
    int main(){
        ios::sync_with_stdio(false);
        int n;
        cin>>n;
        int i;
        string s;
        cin>>s;
        s=" "+s;
        for(i=1;i<(int)s.size();i++){
            if(s[i]=='?'){
                num1[26].push_back(i);
            }
            else{
                int x=s[i]-'a';
                num1[x].push_back(i);
            }
        }
        cin>>s;
        s=" "+s;
        for(i=1;i<(int)s.size();i++){
            if(s[i]=='?')
                num2[26].push_back(i);
            else{
                int x=s[i]-'a';
                num2[x].push_back(i);
            }
        }
        int cnt=0;
        for(i=0;i<26;i++){
            while((int)num1[i].size()&&(int)num2[i].size()){
                int x=num1[i].back();
                int y=num2[i].back();
                num1[i].pop_back();
                num2[i].pop_back();
                ans.push_back({x,y});
            }
            while((int)num1[i].size()){
                res1.push_back(num1[i].back());
                num1[i].pop_back();
            }
            while((int)num2[i].size()){
                res2.push_back(num2[i].back());
                num2[i].pop_back();
            }
        }
        for(auto x:res2){
            if(num1[26].size()){
                ans.push_back({num1[26].back(),x});
                num1[26].pop_back();
            }
        }
        for(auto x:res1){
            if(num2[26].size()){
                ans.push_back({x,num2[26].back()});
                num2[26].pop_back();
            }
        }
        while((int)num1[26].size()&&(int)num2[26].size()){
            int x=num1[26].back();
            int y=num2[26].back();
            num1[26].pop_back();
            num2[26].pop_back();
            ans.push_back({x,y});
        }
        cout<<ans.size()<<endl;
        for(auto x:ans){
            cout<<x.first<<" "<<x.second<<endl;
        }
        return 0;
    }
    View Code

    E题

    很明显的二分算法,答案的轮数具有单调性,因此枚举每一位,以他结束的答案,之后全部答案取min就是最后答案

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    typedef pair<int,int> plll;
    const int N=4e5+10;
    const int inf=0x3f3f3f3f;
    ll d[N];
    ll sum[N];
    ll res[N];
    int main(){
        ios::sync_with_stdio(false);
        ll h,n;
        cin>>h>>n;
        int i;
        int flag=0;
        for(i=1;i<=n;i++){
            cin>>d[i];
            sum[i]=sum[i-1]+d[i];
            if(sum[i]<=-h){
                cout<<i<<endl;
                return 0;
            }
        }
        if(sum[n]>=0){
            cout<<-1<<endl;
            return 0;
        }
        ll ans=1e18;
        for(i=1;i<=n;i++){
            ll l=0,r=1e12;
            while(l<r){
                ll mid=l+r>>1;
                if(1.0*sum[n]<=1.0*(-h-sum[i])/mid){
                    r=mid;
                }
                else{
                    l=mid+1;
                }
            }
            ans=min(ans,l*n+i);
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

     F1题,F2题

    只是数据范围的不同,直接拿正解来做,观察到1500,这玩意一看就是n^2做,想了一会,发现每个和都是独立的,因此可以预处理出来所有区间的和,之后对每个和单独讨论

    这一步想到了后面就简单了。后面就是在一些区间内找到不覆盖的最多的区间个数,经典贪心套路,按照右端点排序之后,遇到合适的就放进来

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    typedef pair<int,int> plll;
    const int N=2e6+10;
    const int inf=0x3f3f3f3f;
    ll sum[N];
    int a[N];
    vector<pll> g[N];
    vector<int> num;
    int find(int x){
        return lower_bound(num.begin(),num.end(),x)-num.begin()+1;
    }
    bool cmp(pll a,pll b){
        return a.second<b.second;
    }
    int main(){
        ios::sync_with_stdio(false);
        int n;
        cin>>n;
        int i,j;
        for(i=1;i<=n;i++){
            cin>>a[i];
            sum[i]=sum[i-1]+a[i];
        }
        int ans=0;
        for(i=1;i<=n;i++){
            for(j=0;j<i;j++){
                int x=sum[i]-sum[j];
                num.push_back(x);
            }
        }
        sort(num.begin(),num.end());
        num.erase(unique(num.begin(),num.end()),num.end());
        for(i=1;i<=n;i++){
            for(j=0;j<i;j++){
                int x=sum[i]-sum[j];
                int pos=find(x);
                g[pos].push_back({j+1,i});
            }
        }
        int id=0;
        for(i=1;i<=(int)num.size();i++){
            if(!(int)g[i].size())
                continue;
            sort(g[i].begin(),g[i].end(),cmp);
            int cnt=1;
            int tmp=0;
            for(j=1;j<(int)g[i].size();j++){
                if(g[i][j].first>g[i][tmp].second){
                    cnt++;
                    tmp=j;
                }
            }
            if(cnt>ans){
                ans=cnt;
                id=i;
            }
        }
        cout<<ans<<endl;
        cout<<g[id][0].first<<" "<<g[id][0].second<<endl;
        int tmp=0;
        for(j=1;j<(int)g[id].size();j++){
            if(g[id][j].first>g[id][tmp].second){
                cout<<g[id][j].first<<" "<<g[id][j].second<<endl;
                tmp=j;
            }
        }
        return 0;
    }
    View Code

     G题

    这题贪心过于套路,看出来其实就是跟度数相关,因为每个点连的边要满足条件,并且每个点只有一个父亲,因此父亲点周围的边其实不影响儿子,因此答案就是第k+1大的度数

    而方案就dfs构造一下就行,主要关注你的父亲是啥,记得判断一下。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    typedef pair<int,int> plll;
    const int N=2e6+10;
    const int inf=0x3f3f3f3f;
    int h[N],ne[N],e[N],idx;
    int w[N],in[N];
    int mx;
    int ans[N];
    void add(int a,int b,int c){
        e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
    }
    void dfs(int u,int fa,int x){
        int cnt=1;
        if(cnt==x&&cnt<mx)
            cnt++;
        for(int i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(j==fa)
                continue;
            ans[w[i]]=cnt;
            dfs(j,u,cnt);
            if(cnt<mx)
                cnt++;
            if(cnt==x&&cnt<mx)
                cnt++;
        }
    }
    int main(){
        ios::sync_with_stdio(false);
        memset(h,-1,sizeof h);
        int i;
        int n,k;
        cin>>n>>k;
        for(i=1;i<n;i++){
            int a,b;
            cin>>a>>b;
            add(a,b,i);
            add(b,a,i);
            in[a]++;
            in[b]++;
        }
        sort(in+1,in+1+n);
        reverse(in+1,in+1+n);
        mx=in[k+1];
        dfs(1,-1,0);
        cout<<mx<<endl;
        for(i=1;i<n;i++)
            cout<<ans[i]<<" ";
        cout<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    JavaWeb学习笔记(9)
    JavaWeb学习笔记(8)
    JavaWeb学习笔记(7)
    JavaWeb学习笔记(6)
    JavaWeb学习笔记(5)
    JavaWeb学习笔记(4)
    Plans(Real-Time Update)
    CSP-J2 2020 题解(Updating)
    Lcez#111 yist
    洛谷P1104 生日
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14190974.html
Copyright © 2011-2022 走看看