The Preliminary Contest for ICPC China Nanchang National Invitational C题 Angry FFF Party(大数+矩阵快速幂打表)

 

题目链接:https://nanti.jisuanke.com/t/38222

题意:定义F(X)为一个斐波那契函数(F(1) = F(2) = 1),给定一个整型大数w,若满足w = F(F(s1))+F(F(s2))+....F(F(sk))且任意si\neqsj(1<=i,j<=k,且i\neqj),则输出所有解中字典序最小的序列S,若不满足则输出-1

思路:看w的范围可以判断这是个大数,先给F(F(n))打个表,在longlong范围内只能打出几个数,然后发现增长非常快,w范围内应该没有几个数,而且只有n<=5会出现取值情况有优先解的情况,n>5之后只有有解和无解的区别,所以想到先把所有小于w的F(F(n))都打表,然后从大到小判断w可不可以减去该值,n<=5之后特判(我直接枚举),然后这时候发现java暴力打表空间打不下,于是想到矩阵快速幂,c++矩阵快速幂t了......最后看到群里的大佬说用py,贼快,于是...发现py真是个神奇的语言(然后发现省赛不能用神奇的python,于是老老实实又写了java....代码附在后面)

代码:(python3.7)

def mut(x,y):
    c = [[0,0],[0,0]]
    c[0][0] = x[0][0]*y[0][0]+x[0][1]*y[1][0]
    c[0][1] = x[0][0]*y[0][1]+x[0][1]*y[1][1]
    c[1][0] = x[1][0]*y[0][0]+x[1][1]*y[1][0]
    c[1][1] = x[1][0] * y[0][1] + x[1][1] * y[1][1]
    return c

def power(y):
    p = [[1,1],[1,0]]
    q = [[1,0],[0,1]]
    while(y!=1):
        if (y%2==1):
            y -=1
            q = mut(p,q)
        else:
            y/=2
            p =mut(p,p)
    return mut(p,q)

p = [[1,1],[1,0]]
a = [0,1,1,1]
for i in range(4,30):
    y = power(i-2)
    x = y[0][0]+y[1][0]
    y = power(x-2)
    x = y[0][0]+y[1][0]
    a.append(x)

t = int(input())
for i in range(t):
    w = int(input())
    ans = []
    for j in range(29,5,-1):
        if w>=a[j]:
            w-=a[j]
            ans.append(j)
    v = len(ans)
    if w>10:
        print("-1")
        continue
    if w==1:
        ans.append(1)
    if w==2:
        ans = ans+[2,1]
    if w==3:
        ans = ans+[3,2,1]
    if w==4:
        ans = ans+[4,2,1]
    if w==5:
        ans = ans+[4,3,2,1]
    if w==6:
        ans = ans+[5,1]
    if w==7:
        ans = ans+[5,2,1]
    if w==8:
        ans = ans+[5,3,2,1]
    if w==9:
        ans = ans+[5,4,2,1]
    if w==10:
        ans = ans+[5,4,3,2,1]
    v = len(ans)
    for i in range(v-1,0,-1):
        print(ans[i],end=' ')
    print(ans[0])

 虽然python非常nice,但是一周后发现省赛并没有python编译环境....写了个java,一百多行的java....真是魔鬼

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.text.*;
 
public class Main {
	static Matrix mul(Matrix a, Matrix b) {
		Matrix c = new Matrix();
		for(int i = 0;i<2;i++) {
			for(int j = 0;j<2;j++) {
				c.m[i][j] = BigInteger.ZERO;
				for(int k = 0;k<2;k++)
				    c.m[i][j] = (c.m[i][j].add(a.m[i][k].multiply(b.m[k][j])));
			}
		}
		return c;
	}
	static Matrix cal(Matrix a, BigInteger exp) {
		Matrix p = new Matrix(), q = new Matrix();
		p = a;
		for(int i = 0;i<2;i++) {
			for(int j = 0;j<2;j++) {
				q.m[i][j] = BigInteger.ZERO;
			}
			q.m[i][i] = BigInteger.ONE;
		}
		while(exp.compareTo(BigInteger.ONE)!=0) {
			if(exp.mod(BigInteger.valueOf(2)).compareTo(BigInteger.ONE)==0) {
				exp = exp.subtract(BigInteger.ONE);
				q = mul(p,q);
			}
			else {
				exp = exp.divide(BigInteger.valueOf(2));
			    p = mul(p,p);
			}
		}
		return mul(p,q);
	}
	public static void main(String[] args) {
		int f[] = new int[100];
		f[1] = f[2] = 1;
		Scanner cin = new Scanner(System.in);
		int ans[] = new int[40];
		int cnt = 0;
		BigInteger res[] = new BigInteger[40];
		for(int i = 5;i<30;i++) {
			Matrix x = new Matrix();
			x.m[0][0] = x.m[0][1] = x.m[1][0] = BigInteger.ONE;
			x.m[1][1] = BigInteger.ZERO;
			Matrix a = new Matrix();
			a = cal(x,BigInteger.valueOf(i-2));
			BigInteger y;
			y = a.m[0][0].add(a.m[1][0]);
			a = cal(x,y.subtract(BigInteger.valueOf(2)));
			y = a.m[0][0].add(a.m[1][0]);
            res[i] = y;
		}
		int t = cin.nextInt();
		while(t>0) {
			t--;
			BigInteger w;
			cnt = 0;
			w = cin.nextBigInteger();
			for(int i = 29;i>=6;i--) {
				BigInteger y;
				y = res[i];
				if(w.compareTo(y)>=0) {
					w = w.subtract(y);
					ans[cnt] = i;
					cnt++;
				}
			}
			if(w.compareTo(BigInteger.valueOf(10))==0) {
				ans[cnt++] = 5;
				ans[cnt++] = 4;
				ans[cnt++] = 3;
				ans[cnt++] = 2;
				ans[cnt++] = 1;
				w = BigInteger.valueOf(0);
			}
			else if(w.compareTo(BigInteger.valueOf(9))==0) {
				ans[cnt++] = 5;
				ans[cnt++] = 4;
				ans[cnt++] = 2;
				ans[cnt++] = 1;
				w = BigInteger.valueOf(0);
			}
			else if(w.compareTo(BigInteger.valueOf(8))==0) {
				ans[cnt++] = 5;
				ans[cnt++] = 3;
				ans[cnt++] = 2;
				ans[cnt++] = 1;
				w = BigInteger.valueOf(0);
			}
			else if(w.compareTo(BigInteger.valueOf(7))==0) {
				ans[cnt++] = 5;
				ans[cnt++] = 2;
				ans[cnt++] = 1;
				w = BigInteger.valueOf(0);
			}
			else if(w.compareTo(BigInteger.valueOf(6))==0) {
				ans[cnt++] = 5;
				ans[cnt++] = 1;
				w = BigInteger.valueOf(0);
			}
			else if(w.compareTo(BigInteger.valueOf(5))==0) {
				ans[cnt++] = 4;
				ans[cnt++] = 3;
				ans[cnt++] = 2;
				ans[cnt++] = 1;
				w = BigInteger.valueOf(0);
			}
			else if(w.compareTo(BigInteger.valueOf(4))==0) {
				ans[cnt++] = 4;
				ans[cnt++] = 2;
				ans[cnt++] = 1;
				w = BigInteger.valueOf(0);
			}
			else if(w.compareTo(BigInteger.valueOf(3))==0) {
				ans[cnt++] = 3;
				ans[cnt++] = 2;
				ans[cnt++] = 1;
				w = BigInteger.valueOf(0);
			}
			else if(w.compareTo(BigInteger.valueOf(2))==0) {
				ans[cnt++] = 2;
				ans[cnt++] = 1;
				w = BigInteger.valueOf(0);
			}
			else if(w.compareTo(BigInteger.valueOf(1))==0) {
				ans[cnt++] = 1;
				w = BigInteger.valueOf(0);
			}
			if(w.compareTo(BigInteger.valueOf(0))==0) {
				for(int i = cnt-1;i>0;i--) {
					System.out.print(ans[i]+" ");
				}
				System.out.println(ans[0]);
			}
			else {
				System.out.println("-1");
			}
		}
	}
}
class Matrix{
	BigInteger m[][] = new BigInteger[5][5];
}

 

你可能感兴趣的:(大数-Python,大数-JAVA)