*TEST 7 for NOIP 玄学解题 (150/300)

来源:互联网 发布:论坛软件有哪些 编辑:程序博客网 时间:2024/05/29 16:15

头更更大

这个10月完就要去搞NOIP了。。。

10月30天也就3次测试。。。为保佑进省一我还是每次测试玩都写个总结。。


boomshakalaka。。。
第一题弱智。。第三题忘了AC自动机了(事实上自己当时也打不来)。。
第二题玄学大法好诶嘿嘿A_A

TEST 7 for NOIP(150/300)

匹配(100/100)

这里写图片描述
这里写图片描述
这里写图片描述
就一类似脑经急转弯的题。

MY/STD.CPP

#include<iostream>#include<iomanip>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<cmath>#include<algorithm>#include<queue>using namespace std;inline int read(){    long long X=0,w=1; char ch=0;    while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}    while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();    return X*w;}inline void write(long long x){     if(x<0) putchar('-'),x=-x;     if(x>9) write(x/10);     putchar(x%10+'0');}int n,x,y;long long ans;int main(){    n = read();    for(int i=1;i<=n;i++)    {        x = read(); y = read();        ans += y-x;    }    for(int i=1;i<=n;i++)    {        x = read(); y = read();        ans += x-y;    }       write(ans);    return 0;}

玩积木(40/100)

这里写图片描述
这里写图片描述
这里写图片描述

。。考试时不知哪根筋抽了搞出了个玄学解题法。。。结果得了40分比暴力还多诶嘿嘿A_A

MY.CPP

#include<iostream>#include<iomanip>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<cmath>#include<algorithm>#include<queue>using namespace std;inline int read(){    long long X=0,w=1; char ch=0;    while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}    while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();    return X*w;}inline void write(long long x){     if(x<0) putchar('-'),x=-x;     if(x>9) write(x/10);     putchar(x%10+'0');}int t,map[7][7];int main(){    std::ios::sync_with_stdio(false);    std::cin.tie(0);std::cout.tie(0);    //freopen("blocks.in","r",stdin);    //freopen("blocks.out","w",stdout);    cin >> t;    while(t--)    {        int ans=0;        for(int k=2;k<=7;k++)        for(int i=1;i<k;i++)        {            cin >> map[i][k-i];            if(map[i][k-i])                ans += abs(map[i][k-i]-k+2);        }        if(map[1][1])            if(ans>20)cout<<"too difficult"<<endl;            else cout<<ans<<endl;        else            if(ans>10)cout<<"too difficult"<<endl;              else cout<<ans*2<<endl;    }    return 0;}

标答本来应该是双向BFS的。。但我玩不来。。然而DFS也能解出来。

STD.CPP

#include<iostream>#include<iomanip>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<cmath>#include<algorithm>#include<queue>using namespace std;inline int read(){    long long X=0,w=1; char ch=0;    while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}    while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();    return X*w;}inline void write(long long x){     if(x<0) putchar('-'),x=-x;     if(x>9) write(x/10);     putchar(x%10+'0');}int str[10][10];int dep;int H(){    int res=0;    for(int i=1;i<=6;i++)    for(int j=1;j<=7-i;j++)        if(str[i][j]!=i+j-2)res++;    return res;}int dx[5]={0,1,-1,0,0};int dy[5]={0,0,0,-1,1};int dfs(int stp,int x,int y){    if(stp>=dep)    {        if(!H())return true;        else return false;    }    if(stp-1+H()>dep)return false;    for(int i=1;i<=4;i++)    {        int xi=x+dx[i],yi=y+dy[i];        if(xi>=1&&xi<=6&&yi>=1&&yi<=6)        if(xi+yi<=x+y+1&&xi+yi>=x+y-1)        {            swap(str[xi][yi],str[x][y]);            if(dfs(stp+1,xi,yi))return true;            swap(str[xi][yi],str[x][y]);        }    }    return false;}int t,map[7][7];int main(){    std::ios::sync_with_stdio(false);    std::cin.tie(0);std::cout.tie(0);    t = read();    while(t--)    {        int ans=0,x,y;        for(int k=1;k<=6;k++)        for(int i=k;i>=1;i--)        {            str[i][k-i+1] = read();            if(!str[i][k-i+1])x=i,y=k-i+1;        }        for(dep=0;dep<=20;dep++)            if(dfs(0,x,y))break;        if(dep>20)cout<<"too difficult"<<endl;        else    cout << dep << endl;    }    return 0;}

字符串(10/100)

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
打的KMP严重超时。。后来发现眼瞎了可以强行AC自动机(然而之前我也打不来)。
裸的AC自动机要TLE。下面给的是普通AC自动机的代码,开满了各种优化还是要超时6个点(其中有两个点甚至只用了1023ms。。。)

MY.CPP

#include<iostream>#include<iomanip>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<queue>using namespace std;inline int read(){    int X=0,w=1; char ch=0;    while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}    while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();    return X*w;}inline void write(long long x){     if(x<0) putchar('-'),x=-x;     if(x>9) write(x/10);     putchar(x%10+'0');}const int N = 10003;const int M = 1e6+3;const int L = 53;int T,n,q,tot,len,ans=0;struct node{    int num,fail;    int son[26];    void init()    {        num = fail = 0;        memset(son,0,sizeof(son));    }}trie[N*L];char s[M];inline void insert(char *s){    int len = strlen(s);    int u = 1;    bool flag = false;    for(int i=0;i<len;++i)    {        if(!trie[u].son[s[i]-'a'])            trie[trie[u].son[s[i]-'a']=++tot].init();                   u = trie[u].son[s[i]-'a'];    }    ++trie[u].num;}int qn,que[N*L];inline void buildFail(){    que[qn=1]=1;    for(int ql=1;ql<=qn;++ql)    {        int u = que[ql],v,w;        for(int i=0;i<26;++i)        {            v = trie[u].fail;                       while(!trie[v].son[i])v = trie[v].fail;                         v=trie[v].son[i],w=trie[u].son[i];            if(w)   trie[w].fail = v,que[++qn] = w;            else    trie[u].son[i] = v;        }    }}inline int get_ans(int l,int r){    int now=1,tmp,jud=0;    for(int i=l;i<r;++i)    {        now = trie[now].son[s[i]-'a'];        tmp = now;        while(tmp)        {            jud += trie[tmp].num;            tmp = trie[tmp].fail;        }    }    return jud; }int rr=0;int main(){    for(int i=0;i<26;++i)trie[0].son[i] = 1;            trie[tot=1].init();    n=read();       q=read();    for(int i=1;i<=n;++i)    {        scanf("%s",s);        int ll=strlen(s);        rr=max(rr,ll);              insert(s);    }    buildFail();    scanf("%s",s);    len = strlen(s);    ans = get_ans(0,len);    write(ans);    cout<<endl;    int pos;    for(int i=1;i<=q;i++)    {        char c;        scanf("%d %c",&pos,&c);        if(s[pos-1]!=c)        {               ans-=get_ans(max(pos-1-rr,0),min(pos-1+rr,len));            s[pos-1] = c;            ans+=get_ans(max(pos-1-rr,0),min(pos-1+rr,len));                    }        write(ans);        cout<<endl;    }    return 0;}

STD.CPP

#include<iostream>#include<iomanip>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<queue>using namespace std;int ans,n,tot,qq,pos,mx,len;int q[100010],tag[100010],fail[100010],f[100010][27];char ch,s[200010];bool vis[100010];inline void Insert(){    int t=0;    for(int i=1;i<=len;++i)    {        if(!f[t][s[i]-'a'])             f[t][s[i]-'a']=++tot;        t=f[t][s[i]-'a'];    }    ++tag[t];}inline void getfail(){    int head=0,tail=1,j;q[1]=0;    while(head^tail)    {        j=q[++head];        if(j)            for(int i=0;i<26;++i)                if(f[j][i])                    fail[f[j][i]]=f[fail[j]][i];            for(int i=0;i<26;++i)                if(!f[j][i])                    f[j][i]=f[fail[j]][i];                else                     q[++tail]=f[j][i];    }    for(int i=1;i<=tail;++i)    {        int u=q[i],v=fail[u];        tag[u]+=tag[v];    }}inline int ac(int st,int end){    int now=0,tmp,ret=0;    for(int i=st;i<=end;++i)    {        now=f[now][s[i]-'a'];        ret+=tag[now];    }    return ret;}int main(){    std::ios::sync_with_stdio(false);    std::cin.tie(0);        cin>>n>>qq;    for(int i=1;i<=n;++i)    {        cin>>s+1;        len=strlen(s+1);        mx=max(mx,len);        Insert();    }    getfail();    cin>>s+1;    len=strlen(s+1);    ans=ac(1,len);    cout<<ans<<endl;    for(int i=1;i<=qq;++i)    {        cin>>pos>>ch;        int l=pos-mx+1,r=pos+mx-1;        if(l<0)   l=0;         if(r>len) r=len;        ans-=ac(l,r);        s[pos]=ch;        ans+=ac(l,r);        cout<<ans<<endl;    }    return 0;}

感想

。。。。。。
平时多背模板!!还有补AC自动机和树形Dp!!!
多练题!!这个周末又去浪了!!
(偏分导学真好用A_A)
https://wenku.baidu.com/view/6c380740be1e650e52ea993f.html

专给一个名为SZM的话:

顶风作案??你每次总结都直接链接我的题目有意思咯?

原创粉丝点击