【題解】Codeforces Round #619 (Div. 2)

比賽鏈接:https://codeforces.com/contest/1301




A. Three Strings(思維)

原題鏈接:https://codeforces.com/contest/1301/problem/A

  • 題意: 給三個相同長度 n 字符串 a,b,c,c 每個字符必須和 a 或者 b 的相應下標字符交換,問經過 n 次變換後 a 是否可以和 b 相同。

  • 思路: a 的字符與 c 的相同或者 b 的字符與 c 的相同既符合交換。如果三個字符都相同也是一樣的,交換後還是 a 和 b 還是相同。

Code:

#include <iostream>
using namespace std;
typedef long long ll;
int main(){
    int t;  cin>>t;
    while(t--){
        string a,b,c;   cin>>a>>b>>c;
        ll len=a.length();
        int flag=1;
        for(int i=0;i<len;i++){
            if(a[i]==c[i] || b[i]==c[i])
                continue;
            else{
                flag=0;
                break;
            }
        }
        if(flag)   cout<<"YES"<<endl;
        else    cout<<"NO"<<endl;
    }
    return 0;
}


B. Motarack’s Birthday(思維)

原題鏈接:https://codeforces.com/contest/1301/problem/B

  • 題意: 給一個長度爲 n 的數組,-1 代表沒有數,你需把空位補上相同的 k ,使得數組相鄰元素中的最大的差值的絕對值最小。
  • 思路: 先找出旁邊有空位的數的最大值和最小值,然後取中間值作爲 k,將空位全部補上,遍歷一遍數組,輸出最大的差值的絕對值。

Code:

#include <iostream>
#include <cstring>
#include <cmath>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N=1e5+10;
int a[N];
int main(){
    int t;  cin>>t;
    while(t--){
        memset(a,0,sizeof(a));
        int n;  cin>>n;
        int maxn=0,minn=inf,flag=0;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            if(a[i]!=-1)    flag=1;
        }
        for(int i=1;i<=n;i++){
            if(a[i]!=-1 && (a[i-1]==-1 || a[i+1]==-1)){
                maxn=max(maxn,a[i]);
                minn=min(minn,a[i]);
            }
        }
 
        if(!flag){
            cout<<0<<' '<<0<<endl;
            continue;
        }
        int mid=(maxn+minn)/2;
        for(int i=1;i<=n;i++){
            if(a[i]==-1)
                a[i]=mid;
        }
        int ans=0;
        for(int i=2;i<=n;i++)
            ans=max(ans,(int)abs(a[i]-a[i-1]));
        cout<<ans<<' '<<mid<<endl;
    }
    return 0;
}


C. Ayoub’s function(思維)

原題鏈接:https://codeforces.com/contest/1301/problem/C

  • 題意: 給長度 n ,m 個 1,構造出一個含 1 子串數量最大的字符串,求最多的含 1 子串數量。

  • 思路:

  1. 用子串總數量減掉不含 1 子串數量即爲含 1 子串數量。一個字符串子串數量爲 n*(1+n) / 2。
  2. m 個 1 把 n-m 個 0 分割成 m+1 部分,要使得含 1 子串數量最多,就得將 0 平均分給這 m+1 部分。a = (n-m) / (m+1)就是平均每份 0 的數量,剩下的 b = (n-m)%(m+1) 就在 m+1 份放個 1 。沒放 1 的部分就有 m+1-b 份。
  3. 放 1 部分不含 0 的子串數量有 b*(a+2)*(a+1)/2 ,不放 1 部分不含 0 的子串數量有 c(1+a)a/2。

Code:

#include <iostream>
using namespace std;
typedef long long ll;
int main(){
    int t;  cin>>t;
    while(t--){
        ll n,m;    cin>>n>>m;
        ll a = (n-m)/(m+1);
        ll b = (n-m)%(m+1);
        ll c = m+1-b;
        cout<<(1+n)*n/2-b*(a+2)*(a+1)/2-c*(1+a)*a/2<<endl;
    }
    return 0;
}


D. Time to Run(構造)

原題鏈接:https://codeforces.com/contest/1301/problem/D

  • 題意: 給一個 n*m 的圖,路線在圖中已標出,問能否在圖中走 k 步,路線不能重複,點可以重複。如果不能走,輸出“NO”,否則輸出 “YES” ,總步驟,每個步驟不能超出 4 個步數,並且總步驟數不能超過 3000 次。

  • 思路: 走法如圖所示
    在這裏插入圖片描述

  1. 當沒走到第 m 列時,每一列都要進行 n-1 次 “D”,n-1 次 “RLU”,1 次 “R”。
  2. 當走到第 m 列時,要進行 n-1 次 “D”,n-1 次 “U”,m-1 次 “L”。

Code:

#include <iostream>
#include <vector>
using namespace std;
struct node{
    int cnt;
    string str;
    node(int sum,string s){
        cnt=sum;
        str=s;
    }
};
vector<node> a;
void push(node x){
    if(x.cnt!=0)
        a.push_back(x);
}
int main(){
    int n,m,k;  cin>>n>>m>>k;
    if(4*n*m-2*n-2*m<k)
        cout<<"NO"<<endl;
    else{
        cout<<"YES"<<endl;
        int cow=1;
        while(k){
            if(cow!=m){
                if(k>=(n-1)){
                    push({n-1,"D"});
                    k-=(n-1);
                }
                else{
                    push({k,"D"});
                    k=0;
                }
                if(k==0)    break;
                if(k>=3*(n-1)){
                    push({n-1,"RLU"});
                    k-=3*(n-1);
                }
                else{
                    push({k/3,"RLU"});
                    if(k%3==1)  push({1,"R"});
                    else if(k%3==2) push({1,"RL"});
                    k=0;
                }
                if(k==0)    break;
                if(k>=1){
                    push({1,"R"});
                    k--;
                }
            }
            else{
                if(k>=n-1){
                    push({n-1,"D"});
                    k-=(n-1);
                }
                else{
                    push({k,"D"});
                    k=0;
                }
                if(!k)  break;
                if(k>=n-1){
                    push({n-1,"U"});
                    k-=(n-1);
                }
                else{
                    push({k,"U"});
                    k=0;
                }
                if(!k)  break;
                if(k>=m-1){
                    push({m-1,"L"});
                    k-=(m-1);
                }
                else{
                    push({k,"L"});
                    k=0;
                }
            }
            cow++;
        }
        cout<<a.size()<<endl;
        for(int i=0;i<a.size();i++)
            cout<<a[i].cnt<<' '<<a[i].str<<endl;
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章