比赛地址:http://acm.hust.edu.cn:8080/judge/contest/view.action?cid=18020#overview
时间:2012-12-10 18:20
好吧,我组织的校赛,都是CF原题,有兴趣的可以来虐场= =
纯粹骗点击量:P
第一题:给你一个棋盘的涂色方案,要你求出至少需要多少画能搞定
分析:注意全部涂满只需要8画,其他的就是有整行或整列的就加1
好吧我把continue写成break了,wa了好几次T_T
代码:
#include<cstdio> #include<iostream> #include<cstring> using namespace std; char a[11][11]; int count() { int i,j,ret=0; for(i=0;i<8;++i) if(a[i][0]=='B') { for(j=0;j<8;++j) if(a[i][j]!='B')break; if(j<8)continue; ++ret; } if(ret==8)return ret; for(j=0;j<8;++j) if(a[0][j]=='B') { for(i=0;i<8;++i) if(a[i][j]!='B')break; if(i<8)continue; ++ret; } return ret; } int main() { for(int i=0;i<8;++i) scanf("%s",a[i]); printf("%d\n",count()); return 0; }
第二题:模拟内存管理,每次可以申请内存块,删除内存块,整理内存块
分析:由于数据太小,直接开个数组暴力模拟内存的使用即可,容易出错的地方是,删除的时候,内存标号可能很大,或者小于0,这个会RE,还有整理内存我写挫了,wa了好久= =
代码:
#include<cstdio> #include<iostream> #include<cstring> using namespace std; const int mm=111; int a[mm],b[mm]; char op[22]; int i,j,n,m,t,id; int main() { while(~scanf("%d%d",&t,&m)) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); id=0; while(t--) { scanf("%s",op); if(op[0]=='a') { scanf("%d",&n); for(j=0,i=1;i<=m;++i) if(!a[i]) { if(++j>=n)break; } else j=0; if(j>=n) { b[++id]=1; while(n--)a[i--]=id; printf("%d\n",id); } else puts("NULL"); } if(op[0]=='e') { scanf("%d",&n); if(n<1||n>id||!b[n])puts("ILLEGAL_ERASE_ARGUMENT"); else { b[n]=0; for(i=1;i<=m;++i) if(a[i]==n)a[i]=0; } } if(op[0]=='d') for(j=0,i=1;i<=m;++i) if(a[i]) { a[++j]=a[i]; if(i>j)a[i]=0; } } } return 0; }
分析:拓展欧几里德的应用,没什么好说的,完全不会,直接被虐成渣T_T
代码(网上抄的):
#include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long LL; void gcd(LL a, LL b, LL& d,LL& x, LL& y){ if(!b){d=a; x=1; y=0; } else {gcd(b,a%b,d,y,x); y -= x*(a/b); } } int main(){ LL a,b,c,d,x,y; cin >> a >> b >> c; gcd(a,b,d,x,y); if(c%d != 0) puts("-1"); else cout << -x*(c/d) << " " << -y*(c/d) << endl; return 0; }
分析:这题就是题目难理解一点,其他的就是怎么求所以回文词了,想了一会儿,发现可以用KMP来做,具体就是把原串当作匹配串,倒过来匹配,当匹配的长度,大于等于当前的下标,这说明出现回文了,具体自己想想就知道了,剩下的就是求这些回文词的度了,呵呵,我直接写了个递归暴力求了,貌似可以用DP汗~~~
代码:
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int mm=5555555; int p[mm]; char a[mm]; bool is[mm]; int i,j,k,n,ans; int count(int r) { if(!r)return 1; int ret=1; while(r>0) { r=(r-1)>>1; if(is[r])++ret; else break; } return ret; } int main() { while(~scanf("%s",a)) { memset(is,0,sizeof(is)); n=strlen(a); p[0]=j=-1; for(i=1;i<n;++i) { while(j>-1&&a[j+1]!=a[i])j=p[j]; if(a[j+1]==a[i])++j; p[i]=j; } j=-1; for(i=n-1;i>=0;--i) { while(j>-1&&a[j+1]!=a[i])j=p[j]; if(a[j+1]==a[i])++j; while(j>=i) { is[i+j]=1; j=p[j]; } } for(ans=i=0;i<n;++i) if(is[i])ans+=count(i); printf("%d\n",ans); } return 0; }
分析:这题比较烦人,懒得做了,就说说想法吧,直接用宏定义的串替换原串,直到不能替换,那就剩下一个多个元素的式子,然后把所以宏定义的字符串两边加上括号,照前面的方法替换成一个式子,然后随机生成每个元素的值,计算两个式子的值是否一致,多次随机,保证两个式子的值相同,说明无二意性,否则不满足。。。
具体大家做一下吧,最近考试周T_T