第35次CSP认证第三题-补丁应用(50分)

// https://sim.csp.thusaac.com/contest/35/problem/2

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

const int N=2010, INF=0x3f3f3f3f;

int n;
string a[N];

// string diff[N];
// int idx;

string pre[N];
int pre_idx;

string aft[N];
int aft_idx;

string tmp[N];
int tmp_idx;

int pre_sum=0;
int add=0;


void damage(){
    puts("Patch is damaged.");
}

int parse_num(string str){
    if(str=="") return -1;
    for(int i=0;i<str.size();i++){
        if(str[i]<'0' || str[i]>'9') return -1;
        if(i==0 && str[i]=='0') return -1;
    }
    return stoi(str);
}

struct Node{
    int NN, MM, nn, mm; 
};
pair<bool, Node> parse_head(string str){
    if(str.substr(0, 4)!="@@ -") return {false, Node()};

    // cout<<"111"<<endl;

    int i=4;
    while(i<str.size() && str[i]!=',') i++;
    int NN=parse_num(str.substr(4, i-4));
    if(NN==-1) return {false, Node()};

    // cout<<"222"<<endl;

    int j=++i;
    while(j<str.size() && str[j]!=' ') j++;
    int MM=parse_num(str.substr(i, j-i));
    if(MM==-1) return {false, Node()};

    // cout<<"333"<<endl;

    if(j+1>=str.size()) return {false, Node()};
    if(str[++j]!='+') return {false, Node()};

    // cout<<"444"<<endl;
    
    int k=++j;
    while(k<str.size() && str[k]!=',') k++;
    int nn=parse_num(str.substr(j, k-j));
    if(nn==-1) return {false, Node()};

    // cout<<"555"<<endl;

    int u=++k;
    while(u<str.size() && str[u]!=' ') u++;
    int mm=parse_num(str.substr(k, u-k));
    if(mm==-1) return {false, Node()};

    // cout<<"666"<<endl;

    if(u+1>=str.size()) return {false, Node()};
    if(str[++u]!='@') return {false, Node()};
    if(u+1>=str.size()) return {false, Node()};
    if(str[++u]!='@') return {false, Node()};

    // cout<<"777"<<endl;

    return {true, {NN, MM, nn, mm}};
}

void work(){
    cin>>n;
    getchar();
    for(int i=1;i<=n;i++){
        getline(cin, a[i]);
        // cout<<a[i]<<endl;
    }

    string str;
    string head;

    while(getline(cin, str) && str[0]!='@') {}
    head=str;
    
    if(head.empty()){
        damage();
        return;
    } 

    while(true){
        // idx=0;
        pre_idx=0, aft_idx=0, tmp_idx=0;

        // cout<<"head: "<<head<<endl;
        auto[f, node]=parse_head(head);
        auto[NN, MM, nn, mm]=node;
        // cout<<f<<" "<<NN<<" "<<MM<<" "<<nn<<" "<<mm<<endl;
        if(!f){
            damage();
            return;
        }

        NN+=add;
        if(NN<pre_sum){
            // cout<<"NN error"<<endl;
            damage();
            return;
        }

        while(getline(cin, str) && str[0]!='@'){
            // diff[idx++]=str;

            if(str[0]=='#')           continue;// 1
            else if(str[0]=='-')      pre[pre_idx++]=str.substr(1);
            else if(str[0]=='+')      aft[aft_idx++]=str.substr(1);
            else if(str[0]==' ') {
                pre[pre_idx++]=str.substr(1);
                aft[aft_idx++]=str.substr(1);
            }else{
                damage();
                return;
            }

        } 

        // for(int i=0;i<idx;i++) cout<<"diff: "<<diff[i]<<endl;

        // for(int i=0;i<pre_idx;i++) cout<<"pre: "<<pre[i]<<endl;
        // for(int i=0;i<aft_idx;i++) cout<<"aft: "<<aft[i]<<endl;
        if(pre_idx!=MM){
            damage();
            return;
        }
        if(aft_idx!=mm){
            damage();
            return;
        }


        // delta process
        int delta=INF;
        int i=pre_sum;
        while(i<=n){
            if(a[i]==pre[0]){
                bool f1=true;
                for(int j=0;j<pre_idx && i+j<=n;j++)
                    if(a[i+j]!=pre[j]){
                        f1=false;
                        break;
                    }
                if(f1){
                    delta=i-NN;
                    break;
                } 
            }
            i++;
        }

        if(delta==INF) {
            damage();
            return ;
        } 

        if(abs(delta)>=MM){
            damage();
            return;
        }

        for(int j=i+pre_idx;j<=n;j++) tmp[tmp_idx++]=a[j];

        // for(int j=0;j<tmp_idx;j++) cout<<"tmp: "<<tmp[j]<<endl;
        
        int k=i;
        for(int j=0;j<aft_idx;j++, k++) a[i+j]=aft[j];

        for(int j=0;j<tmp_idx;j++) a[k+j]=tmp[j];

        n-=pre_idx;
        n+=aft_idx;

        // for(int i=1;i<=n;i++) cout<<"a: "<<a[i]<<endl;

        NN+=delta;
        pre_sum=NN+MM;

        head=str;
        if(head.empty()) break;
    }

    for(int i=1;i<=n;i++) cout<<a[i]<<endl;
}

int main(){
    work();

    // string str="@@ -1,4 +1,5 @@";
    // auto[f, node]=parse_head(str);
    // auto[NN, MM, nn, mm]=node;
    // cout<<f<<" "<<NN<<" "<<MM<<" "<<nn<<" "<<mm<<endl;

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值