蓝桥杯 幂一矩阵 2014年JavaB组决赛第5题


标题:幂一矩阵

    天才少年的邻居 atm 最近学习了线性代数相关的理论,他对“矩阵”这个概念特别感兴趣。矩阵中有个概念叫做幂零矩阵。对于一个方阵 M ,如果存在一个正整数 k 满足 M^k = 0 ,那么 M 就是一个幂零矩阵。(^ 表示乘方)

    atm 不满足幂零矩阵,他自己设想了一个幂一矩阵:对于一个方阵 M ,如果存在一个正整数 k 满足 M^k = I ,其中 I 是单位矩阵,那么 M 就是一个幂一矩阵。

    atm 特别钟情于这样一种方阵:每行每列有且仅有一个 1 。经过 atm 不断实验,他发现这种矩阵都是幂一矩阵。

    现在,他的问题是,给定一个满足以上条件的方阵,他想求最小的 k 是多少。

【输入格式】
第一行一个正整数 n ,表示矩阵大小是 n * n 。
接下来 n 行,每行两个正整数 i j 表示方阵的第 i 行第 j 列为 1。
1 <= i, j <= n 。
行号,列号都从1开始。

【输出格式】
一行。一个正整数,即题目中所说最小的 k 。

【样例输入】
5
3 1
1 2
4 4
2 3
5 5

【样例输出】
3

【数据范围】
对于 30% 的数据满足 n <= 10
对于 60% 的数据答案不超过 10^18
对于 100% 的数据满足 n <= 10000


资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗  < 1000ms


请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。

不理解或者需要交流的同学可以粉我新浪微博@雷锹,私信哟!!!

题目所给的矩阵是一种特殊矩阵,掌握矩阵运算的规律就好,这种大数据最好划整为零

今天老师问我这道题用了什么算法,其实没用很高深的算法,只是在掌握运算规律的前提下不断去减少它的运算量

有兴趣的同志可以研究一下我的求最小公倍数部分


这里提醒同志,不要用什么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;
	}
}


你可能感兴趣的:(蓝桥杯 幂一矩阵 2014年JavaB组决赛第5题)