不理解或者需要交流的同学可以粉我新浪微博@雷锹,私信哟!!!
题目所给的矩阵是一种特殊矩阵,掌握矩阵运算的规律就好,这种大数据最好划整为零
今天老师问我这道题用了什么算法,其实没用很高深的算法,只是在掌握运算规律的前提下不断去减少它的运算量
有兴趣的同志可以研究一下我的求最小公倍数部分
这里提醒同志,不要用什么AUP什么特征方程,抓住最简单的矩阵的n次幂运算规则即可
令A:0 1 0
0 0 1
1 0 0
A*A的第一行为一的只有一个,当A的第一行1的位置和第一列一的位置相同
A*A*A为A*A的行乘以A的列
以此类推:所以保存前者的行1的位置和后者的列1的位置
A*A:row(2,3,1) col(3,1,2)
A*A*A:row(3,1,2)col(3,1,2)
另外索引数组用一下,可以把col去掉,想象少了个for循环,很强大的
再者我分别算出每一行的1的位置经过多少次会等于它的行数,求出这些值的最小公倍数OK
package com.jueshai2014; import java.math.BigInteger; import java.util.HashSet; import java.util.Iterator; import java.util.Scanner; public class _5 { @SuppressWarnings("unused") public static void main(String[] args) { // TODO Auto-generated method stub Scanner scan = new Scanner(System.in); int n = scan.nextInt(); int row[] = new int[n + 1]; int pos [] = new int [n + 1]; int count [] = new int [n + 1]; HashSet<Integer> hashset = new HashSet<Integer>(); for (int i = 0; i < n; i++) { int x = scan.nextInt(); int y = scan.nextInt(); pos[x] = y; row[x] = y; } long time1 = System.currentTimeMillis(); for (int i = 1; i <= n; i++) { hashset.add(exec(row, pos, i)); } Iterator<Integer> it= hashset.iterator(); BigInteger sum = new BigInteger(it.next()+""); while(it.hasNext()){ BigInteger next = new BigInteger(it.next()+""); BigInteger max,min; max= sum.max(next); min = sum.min(next); for(int i = 1; i <= min.intValue(); i++){ BigInteger temp = new BigInteger(i+""); if(max.multiply(temp).mod(min).equals(BigInteger.ZERO)){ sum = max.multiply(temp);break; } } } System.out.println(sum); long time3 = System.currentTimeMillis(); System.out.println("运行时间:"+ (time3-time1)); } private static int exec(int[] row, int[] pos, int i) { int temp = 1; while (true) { row[i] = pos[row[i]]; temp++; if (row[i] == i) break; } if(temp == 2) return 1; return temp; } }