Codeforces Round955 (Div2)--(A~D)题解

Problem - A - Codeforces

思路:如果领先方互换,那么“NO”,否则“YES”。

void solve(){                   A
    int x1,y1; cin>>x1>>y1;
    int x2,y2; cin>>x2>>y2;
    if(x1>y1&&x2>y2||x1<y1&&x2<y2) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
}

Problem - B - Codeforces

思路:找现在的X还差多少可以被Y整除,即need=y-x%y;如此一直模拟即可。但是要注意的是,当X==1之后,是一直在循环的,每y-1次循环回到X==1.所以k%=(y-1)。因为y>=2,所以这样模拟的话,X会递减非常快,只要k足够大,X很快就递减到1,不会TLE。

void solve(){           B
    int x,y,k; cin>>x>>y>>k;
    int need=y-x%y;
    while(k>=need){
        x+=need,k-=need;
        while(x%y==0) x/=y;
        need=y-x%y;
        if(x==1) k%=(y-1);          key!!!!!!!!!!!!!!
    }
    cout<<x+k<<endl;
}

Problem - C - Codeforces

思路:滑动窗口+贪心。

int arr[100005];
void solve(){               C  第一发写的太急了,应该是滑动窗口    写拉了,wa了3发。。
    int n,l,r; cin>>n>>l>>r;
    for(int i=1;i<=n;i++) cin>>arr[i];
    int idxl=1,idxr=1,ans=0,sum=0;
    while(idxr<=n){
        sum+=arr[idxr];
        if(sum>=l&&sum<=r||arr[idxr]>=l&&arr[idxr]<=r) ans++,sum=0,idxl=idxr+1;
        else if(sum>r){
            while(sum>r){   rr和r搞混了。。这里应该是sum>r  不是sum>rr。。。  这都能过样例。。  取名应该区分一点。。不然把自己搞混了
                sum-=arr[idxl];
                idxl++;
            }
            if(sum>=l&&sum<=r||arr[idxr]>=l&&arr[idxr]<=r) ans++,sum=0,idxl=idxr+1;   刚才复制的..这里忘了删rr++..
        }
        idxr++;
    }
    cout<<ans<<endl;
}

Problem - D - Codeforces

思路:一开始山峰的高度差dif是可知的,那么需要弥补这个dif。因为是固定了修改k*k的矩形,那么可以初始化,在每一个这样的k*k矩形中,存在的R山和B山各有几个,它们之间的差difrb就是可以作为弥补dif的值。那么计算出所有的difrb,题目就变成了判断是否存在c1a1+c2a2+...+cnan==dif.
要满足这个条件,那么dif%gcd(a1,a2,...,an)==0即可。初始化的话,我这里先是计算了每一个k*1的矩形的R,B各有几个,利于后面k*k矩阵的遍历移动(滑动窗口一样,只不过这里是长条的移动)。

int n,m,k;
int arr[550][550];
char mark[550][550];
pair<int,int> cnt[550][550];
void solve(){                    D..
    cin>>n>>m>>k;
    int red=0,blue=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>arr[i][j];
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>mark[i][j];
            if(mark[i][j]=='0') red+=arr[i][j];
            else if(mark[i][j]=='1') blue+=arr[i][j];
        }
    }
    bool check=false;
    int dif=red-blue;
    if(k==1||dif==0) check=true;
    for(int i=1;i<=n-k+1;i++){   o(1e8)      初始化
        for(int j=1;j<=m;j++){
            int r=0,b=0;
            for(int f=i;f<=i+k-1;f++){
                if(mark[f][j]=='0') r++;
                else if(mark[f][j]=='1') b++;
            }
            cnt[i][j]={r,b};
        }
    }
    set<int> st;                    st最大是500...st中存在的是因子,需要判断能否通过使用这些因子的倍数组合,组合出dif----多重背包?--不可能,非常庞大X^500次方的级别,X为每个因子最多可以取的次数
    for(int i=1;i<=n-k+1;i++){
        int r=0,b=0;
        for(int j=1;j<=m+1;j++){
            if(j<=k) r+=cnt[i][j].first,b+=cnt[i][j].second;
            else{
                int difrb=abs(r-b);
                if(difrb!=0&&dif%difrb==0) check=true;
                if(difrb!=0) st.insert(difrb);
                if(j!=m+1){
                    r-=cnt[i][j-k].first,b-=cnt[i][j-k].second;
                    r+=cnt[i][j].first,b+=cnt[i][j].second;
                }
            }
        }
    }
    我想知道怎么判断,能否通过使用n个不同的数字a1,a2...an的倍数组合出数字X.即判断是否存在?a1+?a2+...+?an==X,其中?代表系数(可以为0).
    int gcd0=*st.begin();
    for(auto s:st) gcd0=gcd(gcd0,s);
    if(gcd0!=0&&dif%gcd0==0) check=true;
    这个st可以省去,直接计算gcd0
    if(check) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
}
  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Codeforces Round 887是一个程序设计竞赛活动,由Codeforces组织举办。根据引用中的代码,该竞赛的题目要求解决一个序列操作的问题。给定一个长度为n的序列,通过执行一系列操作,使得序列变得非sorted,即非严格递增。具体操作是将序列中[1, i]范围内的数字全部加一,同时将[i+1, n]范围内的数字全部减一。问题要求求解最少需要执行多少次操作才能达到要求。 引用中的代码给出了解决这个问题的实现。代码首先读入序列的长度n和序列a。然后通过判断序列是否已经是非sorted,如果是则直接输出0。接下来,代码遍历序列,求出相邻两个数字的差的最小值。最后,计算出最少需要执行的操作次数,并输出结果。 需要注意的是,引用中的代码只是给出了解决问题的一种实现方式,并不代表Codeforces Round 887的具体题目和解答。要了解该竞赛的具体信息,需要参考Codeforces官方网站或相关资料。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Codeforces Round 887 (Div. 2)](https://blog.csdn.net/qq_36545889/article/details/131905067)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值