先给一下结果:
单刷被虐成狗,ACM打到怀疑人生,I题的二分答案太丢人了,干脆退竞赛吧!!
233,脸上笑嘻嘻,心里。。。。,这个名次也是够讽刺。
上午校内ACM全场划水,草草地a了三道后,坐观队友debug,结果比赛结束也没A,等比赛结束后花了十分钟debug,就A了,队友异样的眼神。
下午没吃晚饭(午饭就随便吃了点),饿着肚子肝CF的ACM,结果不计rating!!我那么努力地a题,结果什么回报都没有?
累觉不爱。
听完hfu的话后已近开场5分钟了,M题有9个人AC了,瞬间从A题切到M,观察,一个曼哈顿距离。
但是一开始脑子不好使,以为要分类讨论,于是构建模型,hfu教练又来找我讨论仙人掌的故事,我一边回答一遍思考简单做法!!
发现自己智商太低了!!就一水题,此题不放题解,请观察code就行了。
#include
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<//智商受创。
return 0;
}
然后发现F题也有人做对了,开始认真看F题。
题意归纳一下就是kh->h,u->oo就行了,所有的string能变就变,运用STL里的string函数库中的insert与erase轻松搞定。因为kh->h时以h为主打,倒着来,找到h判前面的字符判定erase更方便(其实都一样)。
#include
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<
mp.insert(st);
}
cout<return 0;
}
之后暴怒切了一发I题的二分答案,发现暴力判定是错的,没考虑差值的单调性,这样做随便一组样例就能卡死。然后贡献了一发WA。
还是考虑二分答案。
赶紧转战E题(期间谷歌翻译死了一次,网卡了,只能颓QQ,群里大佬A得好快,wsq、wxh他们都要AK了,事实上他们也的确是rank1),思考了一会儿,发现暴力可做,暴力每枚举每一个字符的出现vis。
总之水水就行。
#include
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;iif(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;iif(!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;iif(!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<return 0;
}
G题A得莫名其妙,读完题发现一个暴搜索解决不了两个问(blog主太傻了),所以呢?两个bfs就行了吗!建立边后暴力跑bfs,细节请看code。
vis可以写成bitset更方便统计。
#include
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<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<for(register int i=0;iif(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;
}
找来场外队友?(闲着的wys帮我切H题),这道题全是拼代码量的,基础好code就短,110行也是可以。。。感谢wys先WA一次后让我AC了这道题。(这道题就一个模拟,实在不想写了,还想休息一下呢。)
与上面code完全不一样的code的风格。
#include
#include
#include
#include
using namespace std ;
int N , cnt[128] , iss[128] , tots , lef ;
char ss[400005] , out[400005] ;
/*
21
abcdcbaaaaaaaaaaaaaaa
*/
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