Luogu P2607题解

题目描述:
给出一个n * n的图形,这个图形由0,1,x组成,其中x表示石子的位置,0表示空地,1表示坐标轴。现在需要你求出两个石子所连成直线在指定坐标轴下的一次函数方程。
题解:
这个题其实最大的问题是,情况多不好分析。
都有哪几种情况呢?我们简单说明一下:
1.两点位于坐标轴上。
2.两点中一点位于坐标轴上,另一点不在坐标轴上。
3.两点都不在坐标轴上。
当然这里面又要分斜率和常数项的正负问题…而且这个题目还不好找坐标。
我们可以看出这样的一件事:
当图上的一条线上全部都是1或者x的时候,说明原点的位置就在这条直线上,所以我们的思路就是:先确定原点的位置,然后用原点坐标求得x的坐标,最后求解方程。
AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
char a[20][20];
int ox,oy,jud = 0;
int row[3],cl[3];
void findpoint(int n)
{
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= n;j++){
            if(a[i][j] == 'x' || a[i][j] == '1') jud++;
        }
        if(jud == n){
            oy = i;
            jud = 0;
            break;
        }
        jud = 0;
    }
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= n;j++){
            if(a[j][i] == 'x' || a[j][i] == '1') jud++;
        }
        if(jud == n){
            ox = i;
            jud = 0;
            break;
        }
        jud = 0;
    }
    return;
}
int main()
{
    int n,cnt = 0;
    scanf("%d",&n);
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= n;j++){
            cin >> a[i][j];
            if(a[i][j] == 'x'){
                row[++cnt] = i;
                cl[cnt] = j;
            }
        }
    }
    findpoint(n);//找原点
    // cout << ox << ' ' << oy << endl;
    double x1 = cl[1] - ox,x2 = cl[2] - ox;
    double y1 = oy - row[1],y2 = oy - row[2];
    // cout << x1 << ' ' << x2 << ' ' << y1 << ' ' << y2 << endl; 
    double k,b;
    bool flag1 = 1,flag2 = 1;
    double ans1 = x2 - x1,ans2 = y2 - y1,cnt1 = y1 * x2 - x1 * y2,cnt2 = x2 - x1;
    if(ans1 == 0) printf("x=%.4f\n",x1);
    else if(ans2 == 0) printf("y=%.4f\n",y1);
    else if(cnt1 == 0) printf("y=%.4fx\n",ans2 * 1.0/ans1 * 1.0);
    else{
        if(ans1 * ans2 < 0){
            ans1 = abs(ans1);
            ans2 = abs(ans2);
            flag1 = 0;
        }
        if(cnt1 * cnt2 < 0){
            cnt1 = abs(cnt1);
            cnt2 = abs(cnt2);
            flag2 = 0;
        }
        k = ans2 * 1.0/ans1 * 1.0;b = cnt1 * 1.0/cnt2 * 1.0;
        if(!flag2 && flag1) printf("y=%.4fx-%.4f\n",k,b);
        else if(!flag2 && !flag1) printf("y=-%.4fx-%.4f\n",k,b);
        else if(flag2 & flag1) printf("y=%.4fx+%.4f\n",k,b);
        else if(flag2 && !flag1) printf("y=-%.4fx+%.4f\n",k,b);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CUCKyrie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值