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
  • 相关阅读:
    Get distinct count of rows in the DataSet
    单引号双引号的html转义符
    PETS Public English Test System
    Code 39 basics (39条形码原理)
    Index was outside the bounds of the array ,LocalReport.Render
    Thread was being aborted Errors
    Reportviewer Error: ASP.NET session has expired
    ReportDataSource 值不在预期的范围内
    .NET/FCL 2.0在Serialization方面的增强
    Perl像C一样强大,像awk、sed等脚本描述语言一样方便。
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14190974.html
Copyright © 2011-2022 走看看