zoukankan      html  css  js  c++  java
  • 算法训练 矩阵乘方

    算法训练 矩阵乘方  
    时间限制:1.0s   内存限制:512.0MB
        
    问题描述
      给定一个矩阵A,一个非负整数b和一个正整数m,求A的b次方除m的余数。
      其中一个nxn的矩阵除m的余数得到的仍是一个nxn的矩阵,这个矩阵的每一个元素是原矩阵对应位置上的数除m的余数。
      要计算这个问题,可以将A连乘b次,每次都对m求余,但这种方法特别慢,当b较大时无法使用。下面给出一种较快的算法(用A^b表示A的b次方):
      若b=0,则A^b%m=I%m。其中I表示单位矩阵。
      若b为偶数,则A^b%m=(A^(b/2)%m)^2%m,即先把A乘b/2次方对m求余,然后再平方后对m求余。
      若b为奇数,则A^b%m=(A^(b-1)%m)*a%m,即先求A乘b-1次方对m求余,然后再乘A后对m求余。
      这种方法速度较快,请使用这种方法计算A^b%m,其中A是一个2x2的矩阵,m不大于10000。
    输入格式
      输入第一行包含两个整数b, m,第二行和第三行每行两个整数,为矩阵A。
    输出格式
      输出两行,每行两个整数,表示A^b%m的值。
    样例输入
    2 2
    1 1
    0 1
    样例输出
    1 0
    0 1
     
    ------------------------------------------
    参照一前辈写的
    ----------------------------------
    import java.util.Scanner;
    public class Main {
        static int b,m;
        static int a[][]=new int[2][2],ans[][]=new int[2][2];
        static int temp[][]={{1,1},{1,1}};;
        static void paly(){
            int cnt,cnt2;
            for(cnt=0;cnt<2;cnt++){
                for(cnt2=0;cnt2<2;cnt2++){
                    System.out.print(ans[cnt][cnt2]+" ");
                }
                System.out.println();
            }
        }
        static void cp(int arr1[][],int arr2[][]){
            int cnt,cnt2;
            for(cnt=0;cnt<2;cnt++){
                for(cnt2=0;cnt2<2;cnt2++){
                    arr1[cnt][cnt2]=arr2[cnt][cnt2];
                }
                
            }
        }
        static void mod(int arr[][]){
            int cnt,cnt2;
            for(cnt=0;cnt<2;++cnt){
                for(cnt2=0;cnt2<2;++cnt2)
                    arr[cnt][cnt2]%=m;
            }
            
        }
        static void fun2(int a[][],int b[][]){
            temp[0][0]=a[0][0]*b[0][0]+a[0][1]*b[1][0];
            temp[0][1]=a[0][0]*b[0][1]+a[0][1]*b[1][1];
            temp[1][0]=a[1][0]*b[0][0]+a[1][1]*b[1][0];
            temp[1][1]=a[1][0]*b[0][1]+a[1][1]*b[1][1];
        }
        static void fun(int arr[][],int k){
            if(k==0){
                mod(temp);
                cp(ans,temp);
                return;
            }
            if(k==1){
                mod(ans);
                return;
            }
            if(k==2){
                fun2(a,a);
                cp(ans,temp);
                mod(ans);
                return;
                
            }
            if(k%2==0){
                fun(arr,k/2); 
                fun2(ans,ans);
                cp(ans,temp);
                mod(ans);
                return;
            }
            if(k%2!=0){
                fun(arr,k-1);
                fun2(ans,arr);
                cp(ans,temp);
                mod(ans);
                return;
            }
        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner sc=new Scanner(System.in);
            int cnt,cnt2;
            b=sc.nextInt();
            m=sc.nextInt();
            for(cnt=0;cnt<2;++cnt)
                for(cnt2=0;cnt2<2;++cnt2){
                    a[cnt][cnt2]=sc.nextInt();
                    ans[cnt][cnt2]=a[cnt][cnt2];
                }
            fun(a,b);
            paly();
    
        }
        
        
    
    }
  • 相关阅读:
    python字典及其内置函数详解
    python函数语法学习
    python切片、迭代、生成器、列表生成式等高级特性学习
    Python入门及安装
    node中的加密模块 crypto
    Nodejs+MongoDB+Bootstrap+esj搭建的个人简易博客
    JavaScript的深拷贝和浅拷贝总结
    redux 学习总结
    简述redux(1)
    通信数据转发程序:代理、网关、隧道
  • 原文地址:https://www.cnblogs.com/watchfree/p/5356461.html
Copyright © 2011-2022 走看看