C/C++的简单几何思想

来源:互联网 发布:三菱fx3u编程手册 编辑:程序博客网 时间:2024/06/03 14:38

一、轰炸问题
1、 依次用两点确定一条直线,判断后面的点是否在直线上。
2、 直线方程:(y-y1)/(x-x1)=(y2-y1)/(x2-x1)
3、 为了防止除数为0,将方程式变形(交叉相乘):
(y-y1)(x2-x1)=(y2-y1)(x-x1)

/*轰炸输入文件: "bomb.in"  输出文件: "estdout.pc2"问题描述"我该怎么办?"飞行员klux向你求助。事实上,klux面对的是一个很简单的问题,但是他实在太菜了。klux要想轰炸某个区域内的一些地方,它们是位于平面上的一些点,但是(显然地)klux遇到了抵抗,所以klux只能飞一次,而且由于飞机比较破,一点起飞就只能沿直线飞行,无法转弯。现在他想一次轰炸最多的地方。输入输入由若干组数据构成,每组数据的第一行是整数n,然后是n行整数对组成(1<n<700),每对整数表示一个点的坐标,且没有一个点会出现两次。当n为0时表示输入结束。输出针对每组数据输出一个整数,它表示一条直线能覆盖的最多的点数。输入样本51 12 23 39 1010 110输出样本3【程序说明】1、两点确定一条直线2、点点式直线方程确定直线3、带入法判断第三点在不在直线上4、转除法为加法*/#include<stdio.h>#include "stdlib.h"struct point{       int x,y;} a[700];//平面上的点int main(){    int n, maxPoint, xa, xb, xc, ya, yb, yc, tem;//n:点数 maxPoint:最大点数 tem:每条直线上的点    maxPoint = 0;    scanf("%d", &n);    for (int i = 0; i <= n-1; ++i)    {        scanf("%d%d", &a[i].x, &a[i].y);    }    for (i = 0; i <= n-3; ++i)    {        for (int j = i+1; j <= n-2; ++j)        {            tem=2;            xa=a[i].x; //起点x坐标            ya=a[i].y; //起点y坐标            xb=a[j].x; //终点x坐标            yb=a[j].y; //终点y坐标            for (int k=j+1; k<=n-1; ++k)            {                xc=a[k].x;                yc=a[k].y;                if ((yb-ya)*(xc-xa) == (yc-ya)*(xb-xa))//斜率相等                {                    ++tem;//点数加加                }            }            if (tem > maxPoint)             {                maxPoint = tem;            }        }    }    printf("%d\n",maxPoint);    return 0;}

二、青蛙在网上相识
1、分析题目,建立数学模型
两个青蛙在循环跑到上追逐,各自的步长,步速不等,须在同一时刻跳到同一点,方可判断相遇,结束。也有可能永远不会相遇。
2、建立数学表达式:(x+sm)-(y+sn)=kL;
变型:(n-m)s+kL=x-y
在变型方程式里面,s和k为未知数,其余已知;
3、哪种情况是永不相遇:根据扩展的欧几里得原理有已知方程ax+by=c有整数解需满足条件c%d为0;d为a和b的最大公约数。
4、 根据建立的数学表达式,分别求出对应的a,b,c值。
a=n-m;b=L;c=x-y;
5、 求a与b的最大公约数。
6、 如果有整数解,求经过多少步相遇。
方法一:各自一步步跳,到位置相等退出。
while(front != rear)
{

    front=(front+m) % L;    rear=(rear+n) % L ;    step++;}

方法二:根据相对距离与相对速度求解。
相对距离除以相对速度,如结果不为整数步,则加上一整圈距离再除,知道相除结果为整数步为止。
if((i*L + (y-x))%(m-n) == 0)
{
step = (i*L + (y-x))/(m-n);
break;
}

/*【问题描述】  两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面。它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止。可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置。不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的。但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的。为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面。我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳m米,青蛙B一次能跳n米,两只青蛙跳一次所花费的时间相同。纬度线总长L米。现在要你求出它们跳了几次以后才会碰面。【输入】输入文件名"frogin.txt"输入只包括一行5个整数xym,n,L,其中xy < 20000000000 < m、n < 20000000000 < L < 2100000000。 【输出】输出文件名"frogout.txt"针对输入的数据如果永远不可能碰面则输出一行Impossible,如果可以碰面则输出碰面所需要的跳跃次数。【样例输入】1 2 3 4 5【样例输出】4【程序说明】__int64占32为;x:青蛙A的起始点;y:青蛙B的起点;m:青蛙A的速度;n:青蛙B的速度;构造方程:ax+by=c;设需要s步由题意可知:(x+sm)-(y+sn)=kL;//L的k倍变型:(n-ms+kL=x-y所以:a=n-m;b=L;c=x-y*/#include "stdio.h"__int64 gcd(__int64 a, __int64 b)//辗转相除法求最大公约数{       if(b==0)        return a;       return gcd(b,a%b);}int main(){    __int64 x, y, n, m, L, a, b, c, d, step = 0;    printf("请输入青蛙A所在的位置:");    scanf("%I64d", &x);    printf("请输入青蛙B所在的位置:");    scanf("%I64d", &y);    printf("请输入青蛙A一次跳多少米:");    scanf("%I64d", &m);    printf("请输入青蛙B一次跳多少米:");    scanf("%I64d", &n);    printf("请输入维度线总长:");    scanf("%I64d", &L);    if(n<m)        a = m-n;    else        a = n-m;    b = L;    if(x>y)        c=x-y;    else        c=y-x;    d = gcd(a, b);    if(m==n||c%d != 0)    {        printf("Impossible\n");    }    else    {        unsigned int temp;        if(x>y)        {            temp = x;            x =y;            y = temp;            temp = m;            m = n;            n = temp;        }        for(int i=0;;i++)        {              if(m<n)            {                if((i*L + (L-(y-x)))%(n-m) == 0)                {                    step = (i*L + (L-(y-x)))/(n-m);                    break;                }            }            else if(x<y && m>n)            {                if((i*L + (y-x))%(m-n) == 0)                {                    step = (i*L + (y-x))/(m-n);                    break;                }            }                            }           printf("一共跳%I64d步\n",step);    }       return 0;}/*#include "stdio.h"#include "stdlib.h"unsigned int gcd(unsigned int a, unsigned int b)//辗转相除法求最大公约数{       if(b==0)        return a;       return gcd(b,a%b);}int main(){    unsigned int  front ;    unsigned int  rear ;    unsigned int  step = 0;//4294967295, 最大表示232次方减一,输出格式%u    unsigned int  x, y, n, m, L, a, b, c, d;    printf("请输入青蛙A所在的位置:");    scanf("%d", &x);    printf("请输入青蛙B所在的位置:");    scanf("%d", &y);    printf("请输入青蛙A一次跳多少米:");    scanf("%d", &m);    printf("请输入青蛙B一次跳多少米:");    scanf("%d", &n);    printf("请输入维度线总长:");    scanf("%d", &L);    if(n<m)        a = m-n;    else        a = n-m;    b = L;    //c = x - y;        if(x>y)        c=x-y;    else        c=y-x;    d = gcd(a, b);    if(m==n||c%d != 0)    {        printf("Impossible\n");        return 0;    }    front = x;    rear = y;    while(front != rear)    {        front=(front+m) % L;        rear=(rear+n) % L ;        step++;    }    printf("%u\n", step);    return 0;}*/
0 0
原创粉丝点击