模线性方程

X问题 http://acm.hdu.edu.cn/showproblem.php?pid=1573

用无要求的中国剩余定理求解模线性方程组,当然这个题也有暴力的做法,详情请见nenu contest2

 1 #include<cstdio>
 2 const int M=16;
 3 int a[M],b[M];
 4 int gcd(int a,int b) { //最大公约数
 5     return b?gcd(b,a%b):a;
 6 }
 7 int lcm(int a,int b) { //最小公倍数
 8     return a/gcd(a,b)*b;
 9 }
10 int ext_gcd(int a,int b,int &x,int &y) { //扩展gcd d=gcd(a,b)=a*x+b*y; return d,x,y;
11     int t,ret;
12     if(!b) {
13         x=1;
14         y=0;
15         return a;
16     }
17     ret=ext_gcd(b,a%b,x,y);
18     t=x;
19     x=y;
20     y=t-a/b*y;
21     return ret;
22 }
23 int modular_linear_system(int a[],int b[],int n){//求解模线性方程组(无要求)X mod a[i]=b[i],n个方程
24     int m1,m2,r1,r2,c,d,t,x,y;
25     m1=a[0];
26     r1=b[0];
27     for(int i=1;i<n;i++){
28         m2=a[i];
29         r2=b[i];
30         c=r2-r1;
31         d=ext_gcd(m1,m2,x,y);
32         if(c%d) return -1;
33         t=m2/d;
34         x=(c/d*x%t+t)%t;
35         r1=m1*x+r1;
36         m1=m1*m2/d;
37     }
38     return r1;
39 }
40 int main() {
41     int t,n,m;
42     while(~scanf("%d",&t)) {
43         while(t--) {
44             scanf("%d%d",&n,&m);
45             int sumlcm=1;
46             for(int i=0; i<m; i++) {
47                 scanf("%d",&a[i]);
48                 sumlcm=lcm(sumlcm,a[i]);
49             }
50             for(int i=0; i<m; i++) {
51                 scanf("%d",&b[i]);
52             }
53             int ans=modular_linear_system(a,b,m);
54             if(ans==-1||ans>n) {
55                 puts("0");
56                 continue;
57             }
58             if(ans==0) ans+=sumlcm;
59             int sum=(n-ans)/sumlcm+1;
60             printf("%d\n",sum);
61         }
62     }
63     return 0;
64 }
View Code

 

Strange Way to Express Integers http://poj.org/problem?id=2891

同上,更简单,模板题。

 1 #include<cstdio>
 2 typedef __int64 LL;
 3 const int M=1024;
 4 LL ext_gcd(LL a,LL b,LL &x,LL &y) { //扩展gcd d=gcd(a,b)=a*x+b*y; return d,x,y;
 5     LL t,ret;
 6     if(!b) {
 7         x=1;
 8         y=0;
 9         return a;
10     }
11     ret=ext_gcd(b,a%b,x,y);
12     t=x;
13     x=y;
14     y=t-a/b*y;
15     return ret;
16 }
17 LL modular_linear_system(LL a[],LL b[],LL n){//求解模线性方程组(无要求)X mod a[i]=b[i],n个方程
18     LL m1,m2,r1,r2,c,d,t,x,y;
19     m1=a[0];
20     r1=b[0];
21     for(int i=1;i<n;i++){
22         m2=a[i];
23         r2=b[i];
24         c=r2-r1;
25         d=ext_gcd(m1,m2,x,y);
26         if(c%d) return -1;
27         t=m2/d;
28         x=(c/d*x%t+t)%t;
29         r1=m1*x+r1;
30         m1=m1*m2/d;
31     }
32     return r1;
33 }
34 LL a[M],b[M];
35 int main(){
36     int n;
37     while(~scanf("%d",&n)){
38         for(int i=0;i<n;i++){
39             scanf("%I64d%I64d",&a[i],&b[i]);
40         }
41         printf("%I64d\n",modular_linear_system(a,b,n));
42     }
43     return 0;
44 }
View Code

 

 

Hello Kiki http://acm.hdu.edu.cn/showproblem.php?pid=3579

看了别人的才知道要特判一个并且整除。其实就是最小解如果是零的话,那就应该加上所有ai的lcm,找到第一个正整数解。

 1 #include<cstdio>
 2 const int M=8;
 3 int ext_gcd(int a,int b,int &x,int &y) { //扩展gcd d=gcd(a,b)=a*x+b*y; return d,x,y;
 4     int t,ret;
 5     if(!b) {
 6         x=1;
 7         y=0;
 8         return a;
 9     }
10     ret=ext_gcd(b,a%b,x,y);
11     t=x;
12     x=y;
13     y=t-a/b*y;
14     return ret;
15 }
16 int modular_linear_system(int a[],int b[],int n){//求解模线性方程组(无要求)X mod a[i]=b[i],n个方程
17     int m1,m2,r1,r2,c,d,t,x,y;
18     m1=a[0];
19     r1=b[0];
20     for(int i=1;i<n;i++){
21         m2=a[i];
22         r2=b[i];
23         c=r2-r1;
24         d=ext_gcd(m1,m2,x,y);
25         if(c%d) return -1;
26         t=m2/d;
27         x=(c/d*x%t+t)%t;
28         r1=m1*x+r1;
29         m1=m1*m2/d;
30     }
31     return r1;
32 }
33 int a[M],b[M];
34 int main(){
35     int t,n;
36     while(~scanf("%d",&t)){
37         for(int cas=1;cas<=t;cas++){
38             scanf("%d",&n);
39             for(int i=0;i<n;i++){
40                 scanf("%d",&a[i]);
41             }
42             for(int i=0;i<n;i++){
43                 scanf("%d",&b[i]);
44             }
45             int ans;
46             if(n==1&&!b[0]){
47                 ans=a[0];
48             }
49             else{
50                 ans=modular_linear_system(a,b,n);
51             }
52             printf("Case %d: %d\n",cas,ans);
53         }
54     }
55     return 0;
56 }
View Code

 

 

end

posted on 2014-08-25 12:29  gaolzzxin  阅读(231)  评论(0编辑  收藏  举报