uva1589象棋 紫书习题4-1
看到这题 自己的思路是写个各个子的判断函数,判断将军在不在杀伤范围内 然后列举将军走动的最多四种情况,然后判断有没有生存下来的情况。
可是马 车 炮 将四个子的判断函数都和全局所有子的位置有关,需要开一个二维数组来存储棋盘信息。
由于循环的代码太多了 break不过来了 于是用了goto 可能不太直观。用1代表alive活着,用0代表died死了。
第一次debug 发现自己用scanf中的%c读取字符会读到空格,读不到想要的结果,改成%s读取字母g r h c再将s[0]赋值给字符。然后发现输出为空的情况解除,能正确输出yes和no但答案不正确。
第二次debug,发现自己有一个if语句中的 比较运算符== 写成了赋值运算符 = 导致了结果的出错。更改后,程序无法输出yes,但no为正确的。
第三次debug,发现原因是因为我的思路是如果四个将军的位置都为0 died,则输出yes 将死,可第四个将军的位置可能在九宫格外不合法,被跳过,就没输出yes。增加了一个else语句,确保能输出yes。
至此 样例输入已经通过,开始提交oj。
呃 wa了 ,哪里出了问题呢?通过oj的debug板块找别的样例输入吧,但是比赛场上,就只能自己苦想了。 通过对比发现,错误是因为我的Yes和No只有首字母大写了 而输出要求全部大写。
然后 就ac啦!!! 耗时两个小时 九点到十一点 边写博客边写题的。
自己还不会什么算法,应该说完全不会算法,只能跟着紫书先把语言特性学了,再去攻算法吧。希望自己有机会能参加寒假学校的acm集训。我这个大学开学才入门的菜鸡,也想和那些高中竞赛党竞争呀。
然后由于 自身水平有限 写出来的代码又长 又基础(实在只会用基础语言解题呀)
附上代码
#include<stdio.h>
#include<string.h>
int position[12][12],bgx,bgy;
//帅的判断函数
int g(int i,int j,int x1,int y1)
{
if(j!=y1)return 1;
if(j==y1){for (int i1=x1+1;i1<i;i1++){if(position[i1][j])return 1;}}
return 0;
}
//车的判断函数
int r(int i,int j,int x1,int y1)
{
if(j!=y1&&i!=x1)return 1;
if(j==y1&&i==x1)return 1;
if(j==y1){if(i>x1){i=i^x1;x1=i^x1;i=i^x1;}for (int i1=i+1;i1<x1;i1++){if(position[i1][j])return 1;}}
if(i==x1){if(j>y1){j=j^y1;y1=j^y1;j=j^y1;}for (int j1=j+1;j1<y1;j1++){if(position[i][j1])return 1;}}
return 0;
}
//马的判断函数
int h(int i,int j,int x1,int y1)
{
if(!position[i-1][j]){if(i-2==x1&&j-1==y1){return 0;}if(i-2==x1&&j+1==y1){return 0;}}
if(!position[i+1][j]){if(i+2==x1&&j-1==y1){return 0;}if(i+2==x1&&j-1==y1){return 0;}}
if(!position[i][j-1]){if(i-1==x1&&j-2==y1){return 0;}if(i+1==x1&&j-2==y1){return 0;}}
if(!position[i][j+1]){if(i-1==x1&&j+2==y1){return 0;}if(i+1==x1&&j+2==y1){return 0;}}
return 1;
}
//炮的判断函数
int c(int i,int j,int x1,int y1)
{
int countt=0;
if(j!=y1&&i!=x1)return 1;
if(j==y1&&i==x1)return 1;
if(j==y1){if(i>x1){i=i^x1;x1=i^x1;i=i^x1;}for (int i1=i+1;i1<x1;i1++){if(position[i1][j])countt++;}if(countt==1)return 0;}
if(i==x1){if(j>y1){j=j^y1;y1=j^y1;j=j^y1;}for (int j1=j+1;j1<y1;j1++){if(position[i][j1])countt++;}if(countt==1) return 0;}
return 1;
}
//主函数
int main()
{
// freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);
int n;
next:
while(scanf("%d%d%d",&n,&bgx,&bgy)==3&&n)
{
memset(position,0,sizeof(position));
int totalresult=0;
for(int i=0;i<n;i++)
{
int zi,x,y;
char s[2];
scanf("%s%d%d",&s,&x,&y);zi=s[0];
position[x][y]=zi;
}
if(bgx-1>0){int x1=bgx-1;int y1=bgy;int result=0;
for (int i=0;i<12;i++)
{
for(int j=0;j<12;j++)
{
if(position[i][j])
{
if(position[i][j]=='G'){result=g(i,j,x1,y1);}
else if(position[i][j]=='R'){result=r(i,j,x1,y1);}
else if(position[i][j]=='H'){result=h(i,j,x1,y1);}
else if(position[i][j]=='C'){result=c(i,j,x1,y1);}
if(result==0){goto label1;}
}
if(i==11&&j==11){printf("NO\n");goto next;}
}
}
}
label1:if(bgx+1<4){int x1=bgx+1;int y1=bgy;int result=0;
for (int i=0;i<12;i++)
{
for(int j=0;j<12;j++)
{
if(position[i][j])
{
if(position[i][j]=='G'){result=g(i,j,x1,y1);}
else if(position[i][j]=='R'){result=r(i,j,x1,y1);}
else if(position[i][j]=='H'){result=h(i,j,x1,y1);}
else if(position[i][j]=='C'){result=c(i,j,x1,y1);}
if(result==0){goto label2;}
}
if(i==11&&j==11){printf("NO\n");goto next;}
}
}
}
label2:if(bgy+1<7){int x1=bgx;int y1=bgy+1;int result=0;
for (int i=0;i<12;i++)
{
for(int j=0;j<12;j++)
{
if(position[i][j])
{
if(position[i][j]=='G'){result=g(i,j,x1,y1);}
else if(position[i][j]=='R'){result=r(i,j,x1,y1);}
else if(position[i][j]=='H'){result=h(i,j,x1,y1);}
else if(position[i][j]=='C'){result=c(i,j,x1,y1);}
if(result==0){goto label3;}
}
if(i==11&&j==11){printf("NO\n");goto next;}
}
}
}
label3:if(bgy-1>3){int x1=bgx;int y1=bgy-1;int result=0;
for (int i=0;i<12;i++)
{
for(int j=0;j<12;j++)
{
if(position[i][j])
{
if(position[i][j]=='G'){result=g(i,j,x1,y1);}
else if(position[i][j]=='R'){result=r(i,j,x1,y1);}
else if(position[i][j]=='H'){result=h(i,j,x1,y1);}
else if(position[i][j]=='C'){result=c(i,j,x1,y1);}
if(result==0){printf("YES\n");goto next;}
}
if(i==11&&j==11){printf("NO\n");goto next;}
}
}
}else {printf("YES\n");goto next;}
}
return 0;
}
其实还有很多能优化的地方,加快运算速度,抛去不必要的计算。但由于这题并不考察算法,既然过了,就不优化了。
预祝自己能坚持学习下去吧。