( cf1249 )Codeforces Round #595 (Div. 3)部分题解

A Yet Another Dividing into Teams
题意:n个不同的数,要对n个数进行分组,要求每组里面的任意差值的绝对值不能为1.
为你组数.
思路:很明显最多2组,找里面是否有2个差绝对值为1的,如果有就为2,没有就为 1.

代码

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 2e5+10;
template<typename T>T gcd(T a, T b) {return b==0?a:gcd(b, a%b);}
template<typename T>T exgcd(T a,T b,T &g,T &x,T &y){if(!b){g = a,x = 1,y = 0;}else {exgcd(b,a%b,g,y,x);y -= x*(a/b);}}
#ifndef ONLINE_JUDGE
#define debug(fmt, ...) {printf("debug ");printf(fmt,##__VA_ARGS__);puts("");}
#else
#define debug(fmt, ...)
#endif
typedef long long ll;
const ll mod = 1e9+7;
int a[110];
int vis[man];
  
int main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        //freopen("out.txt","w",stdout);
    #endif
    int t;
    cin >> t;
    while(t--){
        int n;scanf("%d",&n);
        for(int i = 1;i <= n;i++){
            cin >> a[i];
        }  
        sort(a+1,a+1+n);
        int ans = 0;
        for(int i = 1;i <= n-1;i++){
            if(a[i]==a[i+1]-1){
                ans++;
                break;
            }
        }
        if(!ans)printf("1\n");
        else printf("2\n");
    }
    return 0;
}

B2 - Books Exchange (hard version)
题意:略。

思路:①因为肯定是形成一个环的,所以并查集并一下就好了。
②记忆化搜索。

代码

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 3e5+10;
template<typename T>T gcd(T a, T b) {return b==0?a:gcd(b, a%b);}
template<typename T>T exgcd(T a,T b,T &g,T &x,T &y){if(!b){g = a,x = 1,y = 0;}else {exgcd(b,a%b,g,y,x);y -= x*(a/b);}}
#ifndef ONLINE_JUDGE
#define debug(fmt, ...) {printf("debug ");printf(fmt,##__VA_ARGS__);puts("");}
#else
#define debug(fmt, ...)
#endif
typedef long long ll;
const ll mod = 1e9+7;
int a[man];int n;
int dp[man],vis[man];
 
int dfs(int i,int cnt){
    if(dp[i])return dp[i];
    if(i==a[i]||vis[i]==1)return 0;
    vis[i] = 1;
    cnt++;
    dp[i] = dfs(a[i],cnt) + cnt;
    //cout << dp[i] <<  " "  << i << endl;
    vis[i] = 0;
    cnt--;
    return dp[i] - cnt;
}
  
int main() {
    #ifndef ONLINE_JUDGE
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt","w",stdout);
    #endif
    int t;
    cin >> t;
    while(t--){
        cin >> n;
        for(int i = 1;i <= n;i++){
            cin >> a[i];
           // cout << a[i] <<endl;
        }
        memset(dp,0,sizeof(dp)); 
        memset(vis,0,sizeof(vis));
        for(int i = 1;i <= n;i++){
            if(a[i]==i)cout << 1 << " ";
            else cout << dfs(i,0)  << " ";
        }cout << endl;
    }   
    return 0;
}

C2. Good Numbers (hard version)
题意:
好数:有3的幂组成的和,幂相同的都出现一次。
给你一个n,找比n第一个大的好数。

思路:
考虑三进制,如果这个数位好数,肯定三进制上都是0 ,1
如果有2肯定不是好数,那么离这个数最近的好数是多少。
我们肯定要让最后一个2进位变成0,而最后一个2的进位会对之后的进位也会有影响,所有我们找最后一个2之后出现的第一个0的位置,然后0位置之前的数全为0,这位为1,在转换一下就好了。

代码

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 2e5+10;
template<typename T>T gcd(T a, T b) {return b==0?a:gcd(b, a%b);}
template<typename T>T exgcd(T a,T b,T &g,T &x,T &y){if(!b){g = a,x = 1,y = 0;}else {exgcd(b,a%b,g,y,x);y -= x*(a/b);}}
#ifndef ONLINE_JUDGE
#define debug(fmt, ...) {printf("debug ");printf(fmt,##__VA_ARGS__);puts("");}
#else
#define debug(fmt, ...)
#endif
typedef long long ll;
const ll mod = 1e9+7;
ll a[50];
int cnt = 0;
void add(){
    a[0] = 1;
    for(int i = 1;i <= 38;i++){
        a[i] = a[i-1]*3;
    }
}
  
int main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        //freopen("out.txt","w",stdout);
    #endif
    int t;
   // init();
    cin >> t;
    while(t--){
        ll n;
        cin >> n;
        vector<int>sp;
        int pos = -1;
        while(n){
            sp.push_back(n%3);
            if(sp.back()==2)pos = (int)sp.size()- 1;
            n /= 3;
        }
        sp.push_back(0);
        ll tp = 1;
        if(pos!=-1){
            int id = find(sp.begin() + pos ,sp.end(),0) - sp.begin();
            for(int i = id - 1;i >= 0;i--){
                sp[i] = 0;
            }
            sp[id] = 1;
        }
        ll ans = 0;
        //cout << cnt << endl;
        for(int i = 0;i < sp.size();i++){
            ans += 1ll*tp*sp[i];
            tp *= 3;
        }
        cout << ans << endl;
    }
    return 0;
}

D2 - Too Many Segments (hard version)
题意:略;
思路:考虑对于当前l来说,如果当前l不满足,需要减,则我们就减掉r最远的那个区间,因为这不仅减少了当前的影响,还更大的减少对之后的影响。

代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 2e5+10;
template<typename T>T gcd(T a, T b) {return b==0?a:gcd(b, a%b);}
template<typename T>T exgcd(T a,T b,T &g,T &x,T &y){if(!b){g = a,x = 1,y = 0;}else {exgcd(b,a%b,g,y,x);y -= x*(a/b);}}
#ifndef ONLINE_JUDGE
#define debug(fmt, ...) {printf("debug ");printf(fmt,##__VA_ARGS__);puts("");}
#else
#define debug(fmt, ...)
#endif
typedef long long ll;
const ll mod = 1e9+7;
struct node{
    int l,r,id;
    bool operator <(const node &a)const{
        return  r < a.r; 
    }
};
vector<node >sp(man);
priority_queue<node>s;
int vis[man];
 
bool cmp(node &a,node &b){
    return a.l < b.l;
}
  
int main() {
    #ifndef ONLINE_JUDGE
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt","w",stdout);
    #endif
    int n,k;
    cin >> n >> k;
    for(int i = 1;i <= n;i++){
        int l,r;cin >> l >> r;
        sp.push_back(node{l,r,i});
        vis[l]++;
        vis[r+1]--;
    }
    sort(sp.begin(),sp.end(),cmp);
    int sum = 0,ans = 0,id = 0;
    vector<int>res;
    for(int i = 1;i <= man-5;i++){
        sum += vis[i];
        if(sum<=k)continue;
        while(id < sp.size()&&sp[id].l <= i){
            s.push(sp[id]);
            id++;
        }
        while(sum>k){
            node tp = s.top();s.pop();
            sum--;
            ans++;
            vis[tp.r+1]++;
            res.push_back(tp.id);
        }
    }
    cout << ans << endl;
    for(int i = 0;i < res.size();i++){
        cout << res[i] << " ";
    }cout <<endl;
    return 0;
}

E - By Elevator or Stairs?
题意:略
思路:一个简单dp,dp[i][0]表示当前第i层选择楼梯的前i层最小的值。
dp[i][1]表示当前i层选择电梯的前i层的最小值
转移:
dp[i][0] = min(dp[i-1][0],dp[i-1][1]) + a[i];
dp[i][1] = min(dp[i-1][0] + k,dp[i-1][1]) + b[i];

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 2e5+10;
template<typename T>T gcd(T a, T b) {return b==0?a:gcd(b, a%b);}
template<typename T>T exgcd(T a,T b,T &g,T &x,T &y){if(!b){g = a,x = 1,y = 0;}else {exgcd(b,a%b,g,y,x);y -= x*(a/b);}}
#ifndef ONLINE_JUDGE
#define debug(fmt, ...) {printf("debug ");printf(fmt,##__VA_ARGS__);puts("");}
#else
#define debug(fmt, ...)
#endif
typedef long long ll;
const ll mod = 1e9+7;
int a[man],b[man];
int dp[man][2];  
 
int main() {
    #ifndef ONLINE_JUDGE
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt","w",stdout);
    #endif
    int n,k;
    cin >> n >> k;
    for(int i = 2;i <= n;i++)cin >> a[i];
    for(int i = 2;i <= n;i++)cin >> b[i];
    dp[2][0] = a[2];
    dp[2][1] = b[2] + k;
    for(int i = 3;i <= n;i++){
        dp[i][0] = min(dp[i-1][0],dp[i-1][1])+a[i];
        dp[i][1] = min(dp[i-1][0] + k ,dp[i-1][1]) + b[i];
    }
    for(int i = 1;i <= n;i++){
        cout << min(dp[i][1],dp[i][0]) << " ";
    }cout <<endl;
    return 0;
}

F:待补

发布了27 篇原创文章 · 获赞 7 · 访问量 2699

猜你喜欢

转载自blog.csdn.net/weixin_43571920/article/details/102713337
今日推荐