题解 P2067 【Cytus-Holyknight】
这题不好处理的地方就在如何判断x轴和y轴的位置,因为情况很多:
1.两个石子(即两个点)的位置没有覆盖坐标轴
- 两个石子里有一个覆盖了坐标轴
3.两个石子里有两个覆盖了坐标轴
………
开始我想用两个连续的1来判断:
if(c[i][j]=='1'&&c[i][j-1]=='1')xz=i;
if(c[i][j]=='1'&&c[i-1][j]=='1')yz=j;
然后发现他死了,下面这种情况就不能判断了:
0x0
1x1
010
然后我改了一下,我想用一个1加一个0来判断:
if(c[i][j]=='1'&&c[i-1][j]=='0')xz=i;
if(c[i][j]=='1'&&c[i][j-1]=='0')yz=j;
然后他又死了,下面这种情况就死了:
x000000
x111111
1000000
1000000
1000000
1000000
1000000
最后改进了一下,让他即判断左边,还判断右边,就A了:
if(!c1&&c[i][j]=='1'&&c[i-1][j]=='0')xz=i,c1=1;//加上两个bool判断防止重复修改
if(!c2&&c[i][j]=='1'&&c[i][j-1]=='0')yz=j,c2=1;
if(!c1&&c[i][j]=='0'&&c[i-1][j]=='1')xz=i-1,c1=1;
if(!c2&&c[i][j]=='0'&&c[i][j-1]=='1')yz=j-1,c2=1;
输出函数的时候还需要特判两个常函数:
1.如果两个点x坐标相等那么输出x=b;
2.如果两个点y坐标相等那么输出y=b;
3.其他输出y=kx+b;
下面是代码,里面有解释:
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10-48+ch;ch=getchar();}
return x*f;
}
const int maxn=105;
char c[maxn][maxn];
int n,xz,yz;//xz是x轴,yz是y轴
double xl,xr,yl,yr;
bool jd1;//记录是否已经找到了1个点
bool c1,c2;//分别记录是否找到了x轴和y轴
int main()
{
n=read();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>c[i][j];
if(!c1&&c[i][j]=='1'&&c[i-1][j]=='0')xz=i,c1=1;//x轴
if(!c2&&c[i][j]=='1'&&c[i][j-1]=='0')yz=j,c2=1;//y轴
if(!c1&&c[i][j]=='0'&&c[i-1][j]=='1')xz=i-1,c1=1;//x轴
if(!c2&&c[i][j]=='0'&&c[i][j-1]=='1')yz=j-1,c2=1;//y轴
if(c[i][j]=='x')//找到了石子
{
//如果不用一个bool变量记录也可以用数组来保存
if(!jd1)//如果没有找到了第一个石子
{
xl=j;
yl=i;
jd1=1;
}
else //如果已经找到了第一个石子就记录第二个
{
xr=j;
yr=i;
}
}
}
}
//因为上面只记录了在数组里面的位置
//这里要处理出实际位置
//若有不懂大家可以手模一下
xl-=yz;
xr-=yz;
yl=xz-yl;
yr=xz-yr;
//下面是分情况讨论
if(xl==xr)
{
cout<<"x=";
printf("%.4lf\n",xl);
return 0;
}
double k,b;
k=(yr-yl)/(xr-xl);
cout<<"y=";
if(k!=0)printf("%.4lfx",k);
else
{
printf("%.4lf\n",yl);
return 0;
}
b=yl-k*xl;
if(b>0)cout<<'+';//如果b小于0就不用输出+
if(b!=0)printf("%.4lf\n",b);
//如果b等于0就什么也不做
return 0;
}