ACM

2019亚洲区域赛(南昌)网络赛

Posted by lvyonghao on September 8, 2019

2019亚洲区域赛(南昌)网络赛

  • 一场比赛下来发现自身水平远远不够
  • 一共做了三道题 AC一道签到题(丢人了哈)
  • 本篇文章分析一道关于字符串的题目,同时对比我和AC的代码,希望通过模仿来提升自己的算法水平

WX20190908-160021@2x.png


题意

  • 定义了good :当串中包含9102子串并且不包含8102子串
  • 截取串的一段,如果通过删除(0 or more)数字可以使串成为good则输出至少要删除的字符个数,若不能则输出-1
  • 输入: 字符串长度 测试数,要截取字符串的左右区间
  • 输出 至少要删除的字符个数/-1;

我的题解(回答错误/超时)

我的思路很简单,先根据l,r分割字符串,找到字符串中最后一个2,再从2往前找0,以此类推直到找到9和8为止,此时判断各个数字的位置,若出现-1则说明数字不存在,即输出-1,若满足9102,则去遍历字符串寻找所有的8并计数输出。

#include<iostream>
#include <stdio.h>
#include <string>
#include <set>
#include<list>
using namespace std;
int n,q;
string s = "";

int main()
{
    cin >> n >> q;
    cin >> s;
    while(q--)
    {
        int l,r,ans = 0;
        cin >> l >> r;
        string S(s,l - 1,(r - l + 1));
        int one,zero,two,nine,eight;
        two = S.find_last_of('2');
        zero = S.find_last_of('0',two);
        one = S.find_last_of('1'),zero;
        nine = S.find_last_of('9',one);
        eight = S.find_last_of('8',one);
        if(nine != -1 && one != -1 && two != -1 && zero != -1)
        {
            if(eight < 0)
            {
                cout << '0' << endl;
                // cout << nine << one << zero << two << endl;
            }else
            {
                for(int i = 0;i <= eight;i++){
                if(S[i] == '8'){
                    ans++;
                }
            }
            cout << ans << endl;     
            // cout << nine << one << zero << two << endl;   
            }
        }else
        {
            cout << "-1" << endl;
            // cout << nine << one << zero << two << endl;
        }
    }
    return 0;
}

Accept的题解

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
const int inf=0x3f3f3f3f;
char a[maxn];
struct node
{
    int dp[5][5];
    void init(){
        memset(dp,inf,sizeof(dp));
        for(int i=0;i<5;i++) dp[i][i]=0;
    }
    friend node operator * (node a,node b){
        node tmp;//tmp.init();
        memset(tmp.dp,inf,sizeof(tmp.dp));
        for(int i=0;i<5;i++){
            for(int j=0;j<5;j++){
                for(int k=0;k<5;k++){
                    tmp.dp[i][j]=min(tmp.dp[i][j],a.dp[i][k]+b.dp[k][j]);
                }
            }
        }
        return tmp;
    }
}tr[maxn<<2];
void build(int i,int l,int r)
{
    if(l==r)
    {
        tr[i].init();
        int c=a[l]-'0';
        if(c==2) tr[i].dp[0][0]=1,tr[i].dp[0][1]=0;
        if(c==0) tr[i].dp[1][1]=1,tr[i].dp[1][2]=0;
        if(c==1) tr[i].dp[2][2]=1,tr[i].dp[2][3]=0;
        if(c==9) tr[i].dp[3][3]=1,tr[i].dp[3][4]=0;
        if(c==8) tr[i].dp[3][3]=1,tr[i].dp[4][4]=1;
        return;
    }
    int mid=(l+r)>>1;
    build(2*i,l,mid);
    build(2*i+1,mid+1,r);
    tr[i]=tr[2*i]*tr[2*i+1];
}
node query(int i,int l,int r,int x,int y)
{
    node ans;
    ans.init();
    if(x<=l&&r<=y) return tr[i];
    int mid=(l+r)>>1;
    if(x<=mid) ans=ans*query(2*i,l,mid,x,y);
    if(y>mid) ans=ans*query(2*i+1,mid+1,r,x,y);
    return ans;
}
int main()
{
    int n,q,l,r;
    scanf("%d%d",&n,&q);
    scanf("%s",a+1);
    reverse(a+1,a+1+n);
    build(1,1,n);
    for(int i=1;i<=q;i++)
    {
        scanf("%d%d",&l,&r);
        l=n+1-l;
        r=n+1-r;
        int ans=query(1,1,n,r,l).dp[0][4];
        printf("%d\n",ans==inf?-1:ans);
    }
    return 0;
}