在本题中,格点是指横纵坐标皆为整数的点。
为了圈养他的牛,农夫约翰(Farmer John)建造了一个三角形的电网。他从原点(0,0)牵出一根通电的电线,连接格点(n,m)(0<=n<32000,0<m<32000),再连接格点(p,0)(p>0),最后回到原点。
牛可以在不碰到电网的情况下被放到电网内部的每一个格点上(十分瘦的牛)。如果一个格点碰到了电网,牛绝对不可以被放到该格点之上(或许Farmer John会有一些收获)。那么有多少头牛可以被放到农夫约翰的电网中去呢?
PROGRAM NAME: fence9
INPUT FORMAT:
(file fence9.in)
输入文件只有一行,包含三个用空格隔开的整数:n,m和p。
OUTPUT FORMAT:
(file fence9.out)
输出文件只有一行,包含一个整数,代表能被指定的电网包含的牛的数目。
7 5 10
20
第一反应就是按照解析几何的方法做,不过有很多特殊情况,比如会是垂直(n=0或p=0),(p<n或p>n)
WA了几次才全部想到
/* ID: your_id_here PROG: fence9 LANG: C++ */ #include <cstdio> #include <cmath> using namespace std; int n,m,p,ans=0; double k1,k2,b2,y; const double EPS=0.000001; int main() { freopen("fence9.in","r",stdin); freopen("fence9.out","w",stdout); scanf("%d%d%d",&n,&m,&p); if(n==0) { k2=-1.0*m/p; b2=m; for(int x=1;x<p;++x) { y=k2*x+b2; if(abs(y-(int) (y+EPS))<EPS)//判断该点是否为整点;取整是向下取整,所以要加上EPS再取整 y-=1; ans+=(int) (y+EPS); } } else { k1=1.0*m/n; for(int x=1;x<n;++x) { y=k1*x; if(abs(y-(int) (y+EPS))<EPS) y-=1; ans+=(int) (y+EPS); } if(n<p) { k2=1.0*m/(n-p); b2=-k2*p; for(int x=n;x<p;++x) { y=k2*x+b2; if(abs(y-(int) (y+EPS))<EPS) y-=1; ans+=(int) (y+EPS); } } else if(n>p) { k2=1.0*m/(n-p); b2=-k2*p; for(int x=n-1;x>=p;--x) {//由于该线上的点也不符合,所以不必排除它,在总数中减去即可 y=k2*x+b2; ans-=(int) (y+EPS); } } } printf("%d\n",ans); return 0; }