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

来源:互联网 发布:淘宝上大胸内衣 编辑:程序博客网 时间:2024/05/20 01:09

头更更大

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

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


专给一个名为SZM并又引用了我的题的家伙的话:

顶风作案???那你不引用我的题啊?(-_-#)


boomshakalaka。。。
第一题签到题不解释。。第三题瞎搞KMP。。
第二题玄学解题竟然拿了40分诶嘿嘿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<algorithm>#include<cmath>#include<queue>using namespace std;int n,t,ans=0;int a[200];int main(){    cin >> t;    for(int x=1;x<=t;x++)    {        ans = 0;        memset(a,0,sizeof(a));        cin >> n;        for(int i=1;i<=n;i++)   cin >> a[i];        sort(a+1,a+n+1);        ans += 2*a[n]-a[1]-a[2];        if(n%2==0)        {            for(int i=1;i<=n/2-1;i++)                ans += a[n-i]-a[i];            for(int i=1;i<=n/2-2;i+=2)                ans += a[n-i]-a[i+2],                ans += a[n-i-1]-a[i+3];        }        else         {            for(int i=1;i<=n/2;i++)                ans += a[n-i]-a[i];            for(int i=3;i<=n/2;i++)                ans += a[n-i+2]-a[i];        }        cout << "Case " << x << ": " << ans << endl;    }}

玩积木(40/100)

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
考试时不知哪根筋抽了想出来的玄学解题法(当时我还以为是标答)然后比暴力的得分还多的多诶嘿嘿A_A。
就是把读入的图和最开始的图求绝对值之和再特判一下0是否在起点。

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就能过了。
有的大佬还打出了A*算法。。(你这不就是吗)

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自动机要超时6个点(还加了各种优化)。
下面是直接套的:

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;}

题解也是AC自动机。

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;}

感想

多刷题,多做模板。。真的。浪了一个周末都明显感到手感不对了。

阅读全文
0 0
原创粉丝点击