Codeforces Round #783 (Div. 2)

Codeforces Round #783 (Div. 2)

这场真好玩呀

A. Direction Change

感觉在周赛中做过。。。
题中说的走法只可能 ∣ x − y ∣ < = 1 |x-y|<=1 xy<=1才能实现嘛,不然只能绕呀绕一次多走两个边边。

#include <bits/stdc++.h>
using namespace std;

int n,m;
inline void solve()
{
    cin >> n >> m;
    int dx,dy;
    dx=n-1,dy=m-1;
    if(!dx&&!dy) cout << 0 << endl;
    else if(abs(n-m)<=1) cout << dx+dy << endl;
    else if((n==1&&m>2)||(m==1&&n>2)) cout << -1 << endl;
    else {
        int ab=abs(dx-dy); 
        int l=(dx+dy)+ab/2*2;
        cout << l << endl;
    }
}
signed main(){
    int t; cin >> t;
    while(t--) solve();
    return 0;
}
B. Social Distance

对所需间隔从大到小排序,会发现前面几个是必须要完整空出的,但后面间隔依次递减(或不变)可以占用上一次空出的空间,所以依次只需要一侧的空位即可,最后一个不需要空,因为最前面有空余的。

所以所需最少的数量就是需要空位最多的数量乘 2 2 2加其他(非最后一个)需要的空位依次相加(只需要加一次),最后的空位从最前面找,最后的空位不需要加,最后不要忘记加上要做的位置,也就是人数。

#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 1e7+10;
int n,m;
int a[N];
bool cmp(int a,int b){
    return a>b; 
}
inline void solve()
{
    cin >> n >> m;
    for(int i=0;i<n;i++) cin >> a[i];
    if(n>=m) puts("NO");
    else {
        sort(a,a+n,cmp);
        int sum=0;
        sum+=a[0]*2;
        for(int i=1;i<n-1;i++){
            sum+=a[i];
        }
        sum+=n;
        if(sum<=m) puts("YES");
        else puts("NO");
    }
}
signed main(){
    int t; cin >> t;
    while(t--) solve();
    return 0;
}
C. Make it Increasing

原来的做法直接改变了数组,但忘记后续还要用原数组进行操作。

O ( n 2 ) O(n^2) O(n2)的复杂度,数据规模不大可以做,该暴力的时候就得暴力呀。。。

#include <bits/stdc++.h>
#define int long long 
using namespace std;

const int N = 5010;
int n,a[N],res=0x3f3f3f3f3f3f3f3f;

signed main(){
    cin >> n;
    for(int i=0;i<n;i++) cin >> a[i];
    for(int i=0;i<n;i++){
        int pos=i,ans=0;
        ans+=2;
        int time;
        time=1;
        for(int i=pos-1;i>0;i--){
            int up=a[i],down=a[i-1];
            up*=time;
            time=up/down+1;
            ans+=time;
            //a[i-1]*=time;
        }
        time=1;
        for(int i=pos+1;i<n-1;i++){
            int up=a[i],down=a[i+1];
            up*=time;
            time=up/down+1;
            ans+=time;
            //a[i+1]*=time;
        }
        res=min(res,ans);
    }
    cout << res << endl;
    return 0;
}

主要是想记录一下题解的做法,觉得很奇妙,暂时还没来得及搞懂,先记下来,之后再看。

#include <bits/stdc++.h>
 
using namespace std;
long long n, a[5005], ans=1e18;
int main()
{
    cin >> n;
    for (int i=1; i<=n; i++) {
        cin >> a[i];
    }
    for (int pos=1; pos<=n; pos++) {
        long long prev=0, sum=0;
        for (int i=pos-1; i>=1; i--) {
            prev+=a[i]-prev%a[i];
            sum+=prev/a[i];
        }
        prev=0;
        for (int i=pos+1; i<=n; i++) {
            prev+=a[i]-prev%a[i];
            sum+=prev/a[i];
        }
        ans=min(ans, sum);
    }
    cout << ans << "\n";
    return 0;
}
D. Optimal Partition

据说也能写,但。。。应该写不了有时间再看。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值