zoukankan      html  css  js  c++  java
  • POJ 2142

    这道题的难点在于求|x|+|y|的为最小的值吧。想了好久才想出来,发现自己的数学能力确实跟不上。

    可知。x=x0+b/d*t;y=y0-a/d*t;则为

    |x0+b/d*t|+|y0-a/d*t|,仔细想想,可以看成的是两条直线方程y绝对值之和。

    那么,必然最小值只能出现在两条直线方程的两个零点之间,则枚举两个零点之间的值赋于t即可解。

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    using namespace std;
    
    int gcd(int a,int b){
    	if(b==0) return a;
    	return gcd(b,a%b);
    }
    
    void exgcd(int a,int b ,int &x,int &y){
    	if(b==0){
    		x=1;y=0; return;
    	}
    	exgcd(b,a%b,x,y);
    	int t=x;
    	x=y;
    	y=t-a/b*y;
    }
    
    int main(){
    	int a,b,c,x0,y0;
    	while(scanf("%d%d%d",&a,&b,&c),a||b||c){
    		int g=gcd(a,b);
    		a/=g; b/=g; c/=g;
    		exgcd(a,b,x0,y0);
    		x0*=c; y0*=c;  
    		int minc=(1<<31)-1,summ=(1<<31)-1;
    		int l=-(x0)/b,r=(y0)/a;
    		if(l>r){
    			int tmp=l;
    			l=r;
    			r=tmp;
    		}
    	//	cout<<"x0="<<x0<<' '<<"y0="<<y0<<endl;
    	//	cout<<"a="<<a<<' '<<"b="<<b<<endl;
    	//	cout<<l<<' '<<r<<endl;
    		int ansx,ansy;
    		for(int i=l-10;i<=r+10;i++){
    			if(abs(x0+b*i)+abs(y0-a*i)<minc){
    				minc=abs(x0+b*i)+abs(y0-a*i);
    				summ=g*a*abs(x0+b*i)+g*b*abs(y0-a*i);
    				ansx=abs(x0+b*i); ansy=abs(y0-a*i);
    			}
    			else if(abs(x0+b*i)+abs(y0-a*i)==minc){
    				if(g*a*abs(x0+b*i)+g*b*abs(y0-a*i)<summ){
    					summ=g*a*abs(x0+b*i)+g*b*abs(y0-a*i);
    					ansx=abs(x0+b*i); ansy=abs(y0-a*i);
    				}
    			}
    		}
    		printf("%d %d
    ",ansx,ansy);
    	}
    }
    

      

  • 相关阅读:
    HTML、CSS、JS 复习——序
    HTML + CSS短标题(二,三,四文字长度)两端对齐的方式
    Supper关键字
    java的重写
    java重载
    Java继承
    JAVA访问权限控制
    (转)java类初始化顺序
    Java 数组和集合
    Java 方法签名
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/3955703.html
Copyright © 2011-2022 走看看