Codeforces Round #595 (Div. 3)

Codeforces Round #595 (Div. 3)

A. Yet Another Dividing into Teams

相邻两个值个数和的最大值即为最少组数。

#include <bits/stdc++.h>
using namespace std;
void solve(){
    int cnt[110]={0};
    int n;cin>>n;
    for(int i=0;i<n;i++){
        int t;cin>>t;
        ++cnt[t];
    }
    int mx=0;
    for(int i=1;i<=100;i++)
        mx=max(mx,cnt[i]+cnt[i+1]);
    cout<<mx<<"\n";
}
int main()
{
    int t;cin>>t;
    while(t--)
        solve();
    return 0;
}
View Code

B2. Books Exchange (hard version)

找出每个独立的环,环长为周期。

#include <bits/stdc++.h>
using namespace std;
void solve(){
    int n;cin>>n;
    int nx[n];for(int &i:nx) cin>>i,--i;
    bool vis[n]={0};
    int res[n]={0};
    for(int i:nx){
        vector<int> cricle;
        while(!vis[i]){
            cricle.push_back(i);
            vis[i]=true;
            i=nx[i];
        }
        for(int j:cricle) res[j]=cricle.size();
    }
    for(int i=0;i<n;i++) cout<<res[i]<<" \n"[i==n-1];
}
int main()
{
    int t;cin>>t;
    while(t--)
        solve();
    return 0;
}
View Code

C2. Good Numbers (hard version)

转三进制,均为1或0输出原数,否则寻找高于最高为2位小于最高位的最小为0位,若存在则为0位幂次以下位均为0,否则所有位为0,最高位的高一位为1,转十进制输出。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll three[40]={1};
void solve(){
    ll n;cin>>n;
    int bit[40]={0},p=0;
    ll t=n;
    while(t){
        bit[p++]=t%3;
        t/=3;
    }
    int r=-1;
    for(int i=p-1;i>=0;i--)
        if(bit[i]>1){
            r=i;
            break;
        }
    if(r!=-1){
        for(int i=r+1;i<p;i++){
            if(bit[i]==0){
                ll sum=three[i];
                for(int j=i+1;j<p;j++)
                    sum+=bit[j]*three[j];
                cout<<sum<<"\n";
                return;
            }
        }
        cout<<three[p]<<"\n";
    }else
        cout<<n<<"\n";
}
int main()
{
    for(int i=1;i<40;i++)
        three[i]=three[i-1]*3;
    int t;cin>>t;
    while(t--)
        solve();
    return 0;
}
View Code

D2. Too Many Segments (hard version)

从小到大依次枚举每个点,若存在以该点为左端点的区间,插入集合,集合大小为包含该点的区间个数,若集合大小大于k,删除最右端点最大的区间,这样对之后的点最优,若集合中存在以该点为右端点的区间,因为枚举过该点后就没用了,所以需要删除以免影响之后点的集合大小的判断。

#include <bits/stdc++.h>
using namespace std;
const int M=2e5+10;
vector<pair<int,int>> seg[M];
set<pair<int,int>> st;
int main()
{
    int n,k;cin>>n>>k;
    for(int i=1;i<=n;i++){
        int l,r;cin>>l>>r;
        seg[l].emplace_back(r,i);
    }
    vector<int> ans;
    for(int i=0;i<M;i++){
        for(auto j:seg[i])
            st.insert(j);
        while(st.size()>k){
            ans.emplace_back(st.rbegin()->second);
            st.erase(--st.end());
        }
        while(!st.empty()&&st.begin()->first==i){
            st.erase(st.begin());
        }
    }
    cout<<ans.size()<<"\n";
    for(int i:ans) cout<<i<<' ';
    return 0;
}
View Code

E. By Elevator or Stairs?

dp[i][0]是以走楼梯的方式到达第i层,dp[i][1]是以坐电梯的方式到达第i层。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n,c;cin>>n>>c;
    int a[n-1];for(int &i:a) cin>>i;
    int b[n-1];for(int &i:b) cin>>i;
    int dp[n][2];
    dp[0][0]=0;
    dp[0][1]=c;
    for(int i=1;i<n;i++){
        dp[i][0]=min(dp[i-1][0]+a[i-1],dp[i-1][1]+a[i-1]);
        dp[i][1]=min(dp[i-1][0]+b[i-1]+c,dp[i-1][1]+b[i-1]);
    }
    for(int i=0;i<n;i++)
        cout<<min(dp[i][0],dp[i][1])<<' ';
    return 0;
}
View Code

 

posted @ 2020-03-26 18:54  Kanoon  阅读(133)  评论(0)    收藏  举报