比赛地址: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;
}
第三题:题目简单易懂,就是求方程ax+by+c=0的整数解,无解就输出-1
分析:拓展欧几里德的应用,没什么好说的,完全不会,直接被虐成渣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