lzh

刘政
posts - 17, comments - 1, trackbacks - 0, articles - 1

Marbles(UVa 10090)

Posted on 2010-08-22 11:18 lzh525 阅读(585) 评论(0)  编辑 收藏 引用 所属分类: ACM解题报告
/*刚拿此题时一头雾水,当看完一次同余方程时方才有点头绪.....后来在又在求最值问题上遇到麻烦。最后才在数学推导下才AC此题.....第一次深刻体会到数学对解题的重要性....下面说一下我的解题思路.....
1.首先通过Gcd函数求出n1,n2的最大公约数g以及满足条件的x,y:  n1*x+n2*y=n;(递归运用:x0=1,y0=0;x=y1,y=(x1-n1/n2*y1))
显然当n不能被g整除时显然没解....这里有一个问题:Gcd函数求出的x,y为什么刚好能使得|x|+|y|最小??请求数学达人指导
2.求出满足条件的m1,m2使得m1*n1+m2*n2=n  (1):由1得,x*n1+y*n2=g (2)....结合(1(2):m1=n*x/g+t*n2/g,m2=n*y/g-t*n1/g;这里的t是一个参数,但仍能满足(1)式。
3.由m1>=0,m2>=0可得他t1=<t<=t2;(注意t的取值必须为整数)
4.由c=c1*m1+c2*m==》c=num1+t*(c1*n2-c2*n1)....因此c的大小取决于c1*n2-c2*n1的正负以及t的值....之后的过程在代码中很明了了。
 1 #include<iostream>
 2 #include<math.h>
 3 using namespace std;
 4 long Gcd(long p,long q,long *x,long *y)
 5 {
 6     long x1,y1;
 7     long g;
 8     if(q>p)
 9         return (Gcd(q,p,y,x));
10     if(q==0)
11     {
12         *x=1;
13         *y=0;
14         return p;
15     }
16     g=Gcd(q,p%q,&x1,&y1);
17     *x=y1;
18     *y=(x1-p/q*y1);
19     return g;
20 }
21 int main()
22 {
23
24     long n,c1,c2,n1,n2,x,y,gcd,t1,t2,t,a,b;
25     //freopen("c:\\in.txt","r",stdin);
26 //    freopen("c:\\8522.out","w",stdout);
27     while(cin>>n)
28     {
29         if(n==0)
30             break;
31         cin>>c1>>n1>>c2>>n2;
32         gcd=Gcd(n1,n2,&x,&y);
33         t1=ceil(-n*(double)x/(double)n2);
34         t2=floor(n*(double)y/(double)n1);
35         if((t1>t2)||(n%gcd!=0))
36         {
37             cout<<"failed\n";
38             continue;
39         }
40         if(c1*n2>=c2*n1)
41             t=t1;
42         
43         else
44           t=t2;
45         a=n*x/gcd+t*n2/gcd;
46         b=n*y/gcd-t*n1/gcd;
47         cout<<a<<" "<<b<<endl;
48     }
49     return 0;
50 }


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理