https://codeforces.com/contest/1862

Problem - C - Codeforces

可以把图形镜像翻转一下,如果两个图形是完全一样,那么就一定是对称的,翻转过来后发现长变成了宽,利用差分重构一下翻转后的图形,再和原图形判断是否完全相同

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define all(a) a.begin(),a.end()
#define fr(a,i,n) for(int i=a;i<=n;i++)
#define fe(a,i,n) for(int i=n;i>=a;i--)
#define fcf(i,cur) for(int i=cfs.h[cur],sup=cfs.e[i];i;i=cfs.net[i],sup=cfs.e[i])
#define endl "\n"
istream &operator>>(istream &in,pii &a){return in>>a.first>>a.second;};
ostream &operator<<(ostream&,pii &a){return cout<<a.first<<' '<<a.second;};
template<typename T>
istream &operator>>(istream &in,vector<T>&v){T x;in>>x;v.push_back(x);return in;};
template<typename T>
T rmin(T &a,T b){if(a>b)a=b;return a;}
template<typename T>
T rmax(T &a,T b){if(a<b)a=b;return a;}
string YES="YES",Yes="Yes",yes="yes",NO="NO",No="No",no="no";
const int N=2e5+10,M=1e6+10,mod=1e9+7;
string s;
int n,m,k;
int a[N],b[N];
void solve(){
    cin>>n;
    fr(1,i,n)cin>>a[i];
    if(a[1]>n){
        cout<<NO<<endl;
        return ;
    }
    fr(1,i,n+1)b[i]=0;
    b[1]=n;
    fr(1,i,n){
        b[a[i]+1]--;
    }
    fr(1,i,n)b[i]+=b[i-1];
    // fr(1,i,n)cout<<b[i]<<' ';cout<<endl;
    fr(1,i,n){
        if(a[i]!=b[i]){
            cout<<NO<<endl;
            return ;
        }
    }
    cout<<YES<<endl;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t=1;
    cin>>t;
    fr(1,i,t){
        solve();
    }
}

Problem - D - Codeforces

如果总共有n个球,那么最多可以有n*(n-1)/2+n种配合,后面的+n是可以改变的,同时计算一下n个球和n-1个球的差距是小于n的,所以可以通过二分计算最少需要多少球才能让n*(n-1)/2+x(0<=x<=n)满足题目要求的个数

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define all(a) a.begin(),a.end()
#define fr(a,i,n) for(int i=a;i<=n;i++)
#define fe(a,i,n) for(int i=n;i>=a;i--)
#define fcf(i,cur) for(int i=cfs.h[cur],sup=cfs.e[i];i;i=cfs.net[i],sup=cfs.e[i])
#define endl "\n"
istream &operator>>(istream &in,pii &a){return in>>a.first>>a.second;};
ostream &operator<<(ostream&,pii &a){return cout<<a.first<<' '<<a.second;};
template<typename T>
istream &operator>>(istream &in,vector<T>&v){T x;in>>x;v.push_back(x);return in;};
template<typename T>
T rmin(T &a,T b){if(a>b)a=b;return a;}
template<typename T>
T rmax(T &a,T b){if(a<b)a=b;return a;}
string YES="YES",Yes="Yes",yes="yes",NO="NO",No="No",no="no";
const int N=2e5+10,M=1e6+10,mod=1e9+7;
string s;
int n,m,k;
int a[N];
ll check(ll x){
    return (x*(x-1))/2;
}
void solve(){
    ll n;
    cin>>n;
    ll mi=0,mx=2648956421;
    while(mi<=mx){
        ll mid=(mi+mx)>>1;
        if(check(mid)>n){
            mx=mid-1;
        }else{
            mi=mid+1;
        }
    }
    ll ans=mi-1;
    cout<<ans+(n-check(ans))<<endl;
    // cout<<ans<<' '<<n-check(ans)<<endl;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t=1;
    cin>>t;
    fr(1,i,t){
        solve();
    }
}

Problem - E - Codeforces

这个题目首先要转换一下思维,假设你最后一个位置选在i,那么一定会有i*d的损失,这个损失是固定的,所以我们可以枚举最右端,使用优先队列维护我们拿到的m个最大值.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define all(a) a.begin(),a.end()
#define fr(a,i,n) for(int i=a;i<=n;i++)
#define fe(a,i,n) for(int i=n;i>=a;i--)
#define fcf(i,cur) for(int i=cfs.h[cur],sup=cfs.e[i];i;i=cfs.net[i],sup=cfs.e[i])
#define endl "\n"
istream &operator>>(istream &in,pii &a){return in>>a.first>>a.second;};
ostream &operator<<(ostream&,pii &a){return cout<<a.first<<' '<<a.second;};
template<typename T>
istream &operator>>(istream &in,vector<T>&v){T x;in>>x;v.push_back(x);return in;};
template<typename T>
T rmin(T &a,T b){if(a>b)a=b;return a;}
template<typename T>
T rmax(T &a,T b){if(a<b)a=b;return a;}
string YES="YES",Yes="Yes",yes="yes",NO="NO",No="No",no="no";
const int N=2e5+10,M=1e6+10,mod=1e9+7;
string s;
ll n,m,k;
int a[N];
void solve(){
    cin>>n>>m>>k;
    fr(1,i,n)cin>>a[i];
    priority_queue<int,vector<int>,greater<int>>que;
    ll ans=0,sum=0;
    fr(1,i,n){
        if(a[i]<0)continue;
        if(que.size()<m)que.push(a[i]),sum+=a[i];
        else{
            if(que.top()<a[i]){
                sum-=que.top();que.pop();
                sum+=a[i];
                que.push(a[i]);
            }
        }
        ans=max(ans,sum-i*k);
    }
    cout<<ans<<endl;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t=1;
    cin>>t;
    fr(1,i,t){
        solve();
    }
}

Problem - F - Codeforces

二分+背包

水和火的蓝条每一秒固定增长的,所以我们直接二分时间,然后通过背包判断是否能将所有的怪物杀死

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define all(a) a.begin(),a.end()
#define fr(a,i,n) for(int i=a;i<=n;i++)
#define fe(a,i,n) for(int i=n;i>=a;i--)
#define fcf(i,cur) for(int i=cfs.h[cur],sup=cfs.e[i];i;i=cfs.net[i],sup=cfs.e[i])
#define endl "\n"
istream &operator>>(istream &in,pii &a){return in>>a.first>>a.second;};
ostream &operator<<(ostream&,pii &a){return cout<<a.first<<' '<<a.second;};
template<typename T>
istream &operator>>(istream &in,vector<T>&v){T x;in>>x;v.push_back(x);return in;};
template<typename T>
T rmin(T &a,T b){if(a>b)a=b;return a;}
template<typename T>
T rmax(T &a,T b){if(a<b)a=b;return a;}
string YES="YES",Yes="Yes",yes="yes",NO="NO",No="No",no="no";
const int N=2e5+10,M=1e6+10,mod=1e9+7;
string s;
int n,m,k;
int a[N];
ll w,f;
bitset<M>bt;
int check(int t){
    ll tw=w*t,tf=f*t;
    ll sum=0;
    bt.reset();
    bt[0]=1;
    fr(1,i,n){
        sum+=a[i];
        bt|=(bt<<a[i]);
    }
    if(tw>=sum||tf>=sum)return 1;
    int mx=0;
    fe(0,i,tw){
        if(bt[i]){
            mx=i;
            break;
        }
    }
    if(tf>=sum-mx)return 1;
    return 0;
}
void solve(){
    cin>>w>>f;
    cin>>n;
    fr(1,i,n)cin>>a[i];
    int l=0,r=M;
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid)){
            r=mid-1;
        }else{
            l=mid+1;
        }
    }
    cout<<l<<endl;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t=1;
    cin>>t;
    fr(1,i,t){
        solve();
    }
}

Problem - G - Codeforces

题目的结论不太难猜,主要是代码写的很痛苦

观察就可以发现,最终的答案就是对于当前的数组element_max-element_min(最大值减去最小值)再加上相邻两个数差值的最大值.

需要一直维护相邻两个数的差值,重点写好add和del函数,这个题就很简单了.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define all(a) a.begin(),a.end()
#define fr(a,i,n) for(int i=a;i<=n;i++)
#define fe(a,i,n) for(int i=n;i>=a;i--)
#define fcf(i,cur) for(int i=cfs.h[cur],sup=cfs.e[i];i;i=cfs.net[i],sup=cfs.e[i])
#define endl "\n"
istream &operator>>(istream &in,pii &a){return in>>a.first>>a.second;};
ostream &operator<<(ostream&,pii &a){return cout<<a.first<<' '<<a.second;};
template<typename T>
istream &operator>>(istream &in,vector<T>&v){T x;in>>x;v.push_back(x);return in;};
template<typename T>
T rmin(T &a,T b){if(a>b)a=b;return a;}
template<typename T>
T rmax(T &a,T b){if(a<b)a=b;return a;}
string YES="YES",Yes="Yes",yes="yes",NO="NO",No="No",no="no";
const int N=2e5+10,M=1e6+10,mod=1e9+7;
string s;
int n,m,k;
int a[N];
map<int,int>ar1,ar2,cnt;
void add(int x){
    ar1[x]++;
    ar2[-x]++;
    if(ar1[x]>1){
        return ;
    }
    int a=0,c=0;
    if(ar1.upper_bound(x)!=ar1.end())c=ar1.upper_bound(x)->first;
    if(ar2.upper_bound(-x)!=ar2.end())a=-(ar2.upper_bound(-x)->first);
    if(a)cnt[x-a]++;
    if(c)cnt[c-x]++;
    if(a&&c)if(--cnt[c-a]==0)cnt.erase(c-a);
}
void del(int x){
    ar1[x]--;ar2[-x]--;
    if(ar1[x])return ;
    ar1.erase(x);
    ar2.erase(-x);
    int a=0,c=0;
    if(ar1.upper_bound(x)!=ar1.end())c=ar1.upper_bound(x)->first;
    if(ar2.upper_bound(-x)!=ar2.end())a=-(ar2.upper_bound(-x)->first);
    if(a)if(--cnt[x-a]==0)cnt.erase(x-a);
    if(c)if(--cnt[c-x]==0)cnt.erase(c-x);
    if(a&&c)cnt[c-a]++;
}
void solve(){
    cin>>n;
    ar1.clear();ar2.clear();cnt.clear();
    fr(1,i,n)cin>>a[i];
    fr(1,i,n)add(a[i]);
    int q;
    cin>>q;
    int i,x;
    while(q--){
        cin>>i>>x;
        del(a[i]);
        a[i]=x;
        add(a[i]);
        if(cnt.empty())cout<<ar1.rbegin()->first<<' ';
        else 
        cout<<ar1.rbegin()->first+cnt.rbegin()->first<<' ';
    }
    cout<<endl;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t=1;
    cin>>t;
    fr(1,i,t){
        solve();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值