2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Prefer

来源:互联网 发布:js控制标签显示隐藏 编辑:程序博客网 时间:2024/06/07 09:10

先给一下结果:
这里写图片描述
单刷被虐成狗,ACM打到怀疑人生,I题的二分答案太丢人了,干脆退竞赛吧!!
233,脸上笑嘻嘻,心里。。。。,这个名次也是够讽刺。
上午校内ACM全场划水,草草地a了三道后,坐观队友debug,结果比赛结束也没A,等比赛结束后花了十分钟debug,就A了,队友异样的眼神。

下午没吃晚饭(午饭就随便吃了点),饿着肚子肝CF的ACM,结果不计rating!!我那么努力地a题,结果什么回报都没有?

累觉不爱。

听完hfu的话后已近开场5分钟了,M题有9个人AC了,瞬间从A题切到M,观察,一个曼哈顿距离。
但是一开始脑子不好使,以为要分类讨论,于是构建模型,hfu教练又来找我讨论仙人掌的故事,我一边回答一遍思考简单做法!!
发现自己智商太低了!!就一水题,此题不放题解,请观察code就行了。

M

#include<bits/stdc++.h>using namespace std;template<class T>inline void read(T &res){    static char ch;T flag=1;    while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;    while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;}int xf,yf,xs,ys;int main(){    read(xf),read(yf),read(xs),read(ys);    cout<<abs((xs-1)-xf)+abs((xs+1)-xf)+abs((ys+1)-yf)+abs((ys-1)-yf)+4<<endl;    //智商受创。    return 0;}

然后发现F题也有人做对了,开始认真看F题。
题意归纳一下就是kh->h,u->oo就行了,所有的string能变就变,运用STL里的string函数库中的insert与erase轻松搞定。因为kh->h时以h为主打,倒着来,找到h判前面的字符判定erase更方便(其实都一样)。

#include<bits/stdc++.h>using namespace std;template<class T>inline void read(T &res){    static char ch;T flag=1;    while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;    while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;}set<string> mp;int n;int main(){    string st;    string ooo="o";    read(n);    for(register int i=1;i<=n;i++){        cin>>st;int len=st.length();        for(int j=len-1;j>=0;j--){            while(st[j]=='h'&&st[j-1]=='k')st.erase(j-1,1),j--;            while(st[j]=='u')st[j]='o',st.insert(j,ooo),j++;        }    //  cout<<st<<endl;;        mp.insert(st);    }    cout<<mp.size()<<endl;    return 0;}

之后暴怒切了一发I题的二分答案,发现暴力判定是错的,没考虑差值的单调性,这样做随便一组样例就能卡死。然后贡献了一发WA。

赛后才AC的I

还是考虑二分答案。

E

赶紧转战E题(期间谷歌翻译死了一次,网卡了,只能颓QQ,群里大佬A得好快,wsq、wxh他们都要AK了,事实上他们也的确是rank1),思考了一会儿,发现暴力可做,暴力每枚举每一个字符的出现vis。
总之水水就行。

#include<bits/stdc++.h>using namespace std;const int maxn = 1010;;template<class T>inline void read(T &res){    static char ch;T flag=1;    while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;    while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;}bool st[100],dg[26],gf[26];char cst[100],stm[100],mes[26];int m,n,tot;int main(){    read(n);    memset(gf,1,sizeof(gf));    scanf("%s",stm);int len=strlen(stm);    for(register int i=0;i<len;i++){        if(stm[i]=='*')st[i]=1;        else{            cst[i]=stm[i];            dg[stm[i]-'a']=1;        }    }    read(m);    for(register int d=1;d<=m;d++){        scanf("%s",stm);len=strlen(stm);        bool sk=0;        for(register int i=0;i<n;i++){            if(!st[i]){                if(stm[i]!=cst[i]){sk=1;break;}                continue;            }            if(dg[stm[i]-'a']){sk=1;break;}        }        if(!sk){            memset(mes,0,sizeof(mes));            for(register int i=0;i<len;i++){                if(!st[i])continue;                mes[stm[i]-'a']=1;            }            for(register int i=0;i<26;i++)                if(!mes[i])gf[i]=0;        }    }    for(register int i=0;i<26;i++)if(gf[i])tot++;    cout<<tot<<endl;    return 0;}

G

G题A得莫名其妙,读完题发现一个暴搜索解决不了两个问(blog主太傻了),所以呢?两个bfs就行了吗!建立边后暴力跑bfs,细节请看code。
vis可以写成bitset更方便统计。

#include<bits/stdc++.h>using namespace std;const int N=300105;struct data{    int from, to, nxt, pos;    int tes;    data(){}    data(int from,int to,int nxt,int pos,int tes):from(from),to(to),nxt(nxt),pos(pos),tes(tes){}}E[N<<1];int head[N],tot,ap[N],cnt,bp[N],n,m,s;queue<int>que;int ans;bool vis[N+55];inline void adddata(int x,int y,int pos,int tes){    E[++tot]=data(x,y,head[x],pos,tes),head[x]=tot;    if(tes==2)E[++tot]=data(y,x,head[y],pos,-tes),head[y]=tot;}template<class T>inline void  read(T &res){    static char ch;T tes=1;    while((ch=getchar())<'0'||ch>'9')if(ch=='-')tes=-1;res=ch-48;    while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=tes;}int t,a,b;int main(){    read(n),read(m),read(s);    memset(ap,-1,sizeof(ap)),memset(bp,-1,sizeof(bp));    for(register int i=1;i<=m;++i){        read(t),read(a),read(b);        if(t!=2)adddata(a,b,0,1);        else adddata(a,b,++cnt, 2);    }    memset(vis,0,sizeof(vis));    que.push(s);    vis[s]=1;    register int u,v;    while(!que.empty()){        u=que.front();        que.pop();        for(register int c,i=head[u];i;i=E[i].nxt){            if(v=E[i].to,E[i].tes==1){                if(!vis[v])vis[v]=1,que.push(v);            }else{                if(!vis[v])vis[v]=1,que.push(v),ap[E[i].pos]=E[i].tes<0?0:1;            }        }    }    ans=0;for(register int i=0;i<=N;++i)if(vis[i])ans++;    cout<<ans<<endl;    for(register int i=1;i<=cnt;i++)        printf("%c",ap[i]?'+':'-');    putchar('\n');    memset(vis,0,sizeof(vis));    que.push(s);    vis[s]=1;    while(!que.empty()){        u=que.front();        que.pop();        for(register int i=head[u];i;i=E[i].nxt){            if(v=E[i].to,E[i].tes!=1)continue;            if(!vis[v])vis[v]=1,que.push(v);        }    }    ans=0;for(register int i=0;i<=N;++i)if(vis[i])ans++;    cout<<ans<<endl;    for(register int i=0;i<tot;i++){        if(E[i].tes!=1&&E[i].tes>0){            v=E[i].to,u=E[i].from;            if(vis[u]&&!vis[v])bp[E[i].pos]=0;            else bp[E[i].pos] = 1;        }    }    for(register int i=1;i<=cnt; ++i)        printf("%c",bp[i]?'+':'-');    putchar('\n');    return 0;}

H

找来场外队友?(闲着的wys帮我切H题),这道题全是拼代码量的,基础好code就短,110行也是可以。。。感谢wys先WA一次后让我AC了这道题。(这道题就一个模拟,实在不想写了,还想休息一下呢。)
与上面code完全不一样的code的风格。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std ;int N , cnt[128] , iss[128] , tots , lef ;char ss[400005] , out[400005] ;/*21abcdcbaaaaaaaaaaaaaaa*/void print(){    printf( "%d\n" , tots ) ;    int len = lef / tots / 2 ;//半长串    for( int i = 48 ; i <= 122 ; i ++ ){        if( iss[i] ){            tots -- ; cnt[i] -- ;            for( int j = 48 , tlen = 0 ; j <= 122 ; j ++ ){                if( !cnt[j] ) continue ;                if( len - tlen >= cnt[j]/2 ){                    cnt[j] /= 2 ;                    while( cnt[j] ) out[++tlen] = j , cnt[j] -- ;                } else {                    while( len - tlen ){                        out[++tlen] = j ; cnt[j] -= 2 ;                    }                    break ;                }            }            for( int j = 1 ; j <= len ; j ++ ) printf( "%c" , out[j] ) ;            printf( "%c" , i ) ;            for( int j = len ; j >= 1 ; j -- ) printf( "%c" , out[j] ) ;            printf( " " ) ;        }    }    for( int i = 1 ; i <= tots ; i += 2 ){        for( int j = 48 ; j <= 122 ; j ++ ){            while( cnt[j] ){                lef -= 2 ; cnt[j] -= 2 ;                for( int k = 48 , tlen = 0 ; k <= 122 ; k ++ ){                    if( !cnt[k] ) continue ;                    if( len - tlen > cnt[k]/2 ){                        cnt[k] /= 2 ;                        while( cnt[k] ) out[++tlen] = k , cnt[k] -- ;                    } else {                        while( len - tlen ){                            out[++tlen] = k ; cnt[k] -= 2 ;                        }                    }                }                for( int k = 1 ; k <= len ; k ++ ) printf( "%c" , out[k] ) ;                printf( "%c" , j ) ;                for( int k = len ; k >= 1 ; k -- ) printf( "%c" , out[k] ) ;                printf( " " ) ;                for( int k = 48 , tlen = 0 ; k <= 122 ; k ++ ){                    if( !cnt[k] ) continue ;                    if( cnt[k] && len - tlen > cnt[k]/2 ){                        cnt[k] /= 2 ;                        while( cnt[k] ) out[++tlen] = k , cnt[k] -- ;                    } else {                        while( len - tlen ){                            out[++tlen] = k ; cnt[k] -= 2 ;                        }                    }                }                for( int k = 1 ; k <= len ; k ++ ) printf( "%c" , out[k] ) ;                printf( "%c" , j ) ;                for( int k = len ; k >= 1 ; k -- ) printf( "%c" , out[k] ) ;                printf( " " ) ;            }        }    }}void solve(){    if( tots == 0 ){        printf( "1\n" ) ;        for( int i = 1 ; i <= 127 ; i ++ )            if( cnt[i] ){                int tmp = cnt[i] / 2 ;                for( int j = 1 ; j <= tmp ; j ++ ) printf( "%c" , i ) ;            }        for( int i = 127 ; i >= 1 ; i -- )            if( cnt[i] ){                int tmp = cnt[i] / 2 ;                for( int j = 1 ; j <= tmp ; j ++ ) printf( "%c" , i ) ;            }        exit( 0 ) ;    }    for( ; lef >= 2*tots ; lef -= 2 , tots += 2 )        if( lef % tots == 0 && ( lef/tots )%2 == 0 ){            print() ; exit(0) ;        }    printf( "%d\n" , N ) ;    for( int i = 1 ; i <= N ; i ++ )        printf( "%c " , ss[i] ) ;}int main(){/*    for( int i = 1 ; i <= 127 ; i ++ )        printf( "%d %c\n" , i , i ) ; */    scanf( "%d" , &N ) ;    scanf( "%s" , ss + 1 ) ;    for( int i = 1 ; i <= N ; i ++ )        cnt[ ss[i] ] ++ ;    for( int i = 48 ; i <= 122 ; i ++ ){        if( cnt[i]&1 ){            tots ++ ; iss[i] = 1 ;        //  printf( "%c is single\n" , i ) ;        }    }    lef = N - tots ;    solve() ;}

收获?emm=====,还是可以,至少完成了上午ACM不想做硬是塞给队友一道bfs题,晚上欠的还是要还。。。
然后感觉近几年ACM与OI在题目类型上的区别越来越小了(因为越来越多的出题人来自大学里的ACM队吗?)。
值得一做且ORZ

Bitset works much better than FFT: yjq_naive, yfzcsc, mcfx

阅读全文
0 0