输入一个整数n,表示字符串长度(1 ≤ n ≤ 30)
输出一个整数表示有多少个暗黑字符串
2 3
9 21
n = int(raw_input()) if n == 1: print 3 else: # initialization, aa-type:3, ab-type:6 ans = [3, 6] mat = [[1, 1], [2, 1]] temp_ans = [0, 0] temp = [[0, 0], [0, 0]] # number of interation n = n - 2 while n != 0: if n & 1 == 1: # update ans temp_ans[0] = mat[0][0] * ans[0] + mat[0][1] * ans[1] temp_ans[1] = mat[1][0] * ans[0] + mat[1][1] * ans[1] ans[0] = temp_ans[0] ans[1] = temp_ans[1] # update the matrix temp[0][0] = mat[0][0] * mat[0][0] + mat[0][1] * mat[1][0] temp[0][1] = mat[0][0] * mat[0][1] + mat[0][1] * mat[1][1] temp[1][0] = mat[1][0] * mat[0][0] + mat[1][1] * mat[1][0] temp[1][1] = mat[1][0] * mat[0][1] + mat[1][1] * mat[1][1] # assign temp back to mat mat[0][0] = temp[0][0] mat[1][0] = temp[1][0] mat[0][1] = temp[0][1] mat[1][1] = temp[1][1] n = n >> 1 print ans[0] + ans[1]
#include<iostream>
using namespace std;
//主要是推导公式:
//例如:在字符串BAA的后面只能有两种添加字符的方法
//1.添加和末尾相同的字符变成BAAA,一定不是暗黑的字符串
//2.添加和末尾不同的字符串变成BAAB或BAAC,一定不是暗黑字符串
//用dp[0]和dp[1]分别表示上一次的添加方式对应的暗黑字符串的个数
//所以公式为:dp[0] = temp0 + temp1; dp[1] = 2*temp0 + temp1;
long long blackNum(int n){
if(n == 1)return 3;
if(n == 2)return 9;
long long dp[2];
dp[0] = 3;
dp[1] = 6;
for(int i = 2;i<n;i++){
long long temp0 = dp[0];
long long temp1 = dp[1];
dp[0] = temp0 + temp1;
dp[1] = 2*temp0 + temp1;
}
return dp[0]+dp[1];
}
int main(){
int n;
while(cin>>n){
cout<<blackNum(n)<<endl;
}
return 0;
}
import java.util.Scanner; import java.lang.Math; public class Main { public static void main(String args[]){ Scanner sc = new Scanner(System.in); int input = sc.nextInt(); long[] num = new long[input+1]; num[1] = 3; num[2] = 9; for(int i=3; i<=input; i++){ num[i] = 2*num[i-1] + num[i-2]; } System.out.print(num[input]); } }
完全不用推导,规模足够小,递推可以直接过//
// main.cpp
// TestNewCoder
//
// Created by starlight on 2018/4/4.
// Copyright © 2018年 sysu. All rights reserved.
//
#include <iostream>
using namespace std;
long long f[40][4][4], sum;
int n;
int main(int argc, const char * argv[]) {
// insert code here...
cin >> n;
if (n == 1) {
cout << 3;
}
else if (n == 2) {
cout << 9;
}
else {
for (int i = 1 ; i <= 3 ; i++)
for (int j = 1 ; j <= 3 ; j++)
f[2][i][j] = 1;
// 初始化
for (int i = 3 ; i <= n ; i++) {
for (int k1 = 1 ; k1 <= 3 ; k1++) {
for (int k2 = 1 ; k2 <= 3 ; k2++) {
for (int k3 = 1 ; k3 <= 3 ; k3++) {
f[i][k1][k2] += (k1 * k2 * k3 != 6 ? f[i-1][k2][k3] : 0);
}
}
}
}
for (int i = 1 ; i <= 3 ; i++) {
for (int j = 1 ; j <= 3 ; j++) {
sum += f[n][i][j];
}
}
cout << sum;
}
return 0;
}
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.util.Arrays; public class Main { public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String line; while((line = br.readLine()) != null){ int n = Integer.parseInt(line); long[] dp = new long[n + 1]; dp[1] = 3; dp[2] = 9; for(int i = 3; i <= n; i++){ dp[i] = 2*dp[i - 1] + dp[i - 2]; } System.out.println(dp[n]); } } }
import java.io.*; /** * 数学排列组合法,找暗黑的字符串 * 规律: * 当第 1 位固定后,第 2 位有 3 种填法:第 3 位对应的第 2 位有 3 + 2 + 2 种 * ———————————————————————————————— * 第一位 |A * -------------------------------- * 第二位 |AA AB AC * -------------------------------- * 第三位 |AAA AAB AAC ABA ABB ACA ACC * * 从第 4 位开始,如果前一位有 3 种排法(AAA AAB AAC),则本位可以有:3 + 2 + 2 种排法 * 如果前一位有 2 种排法(ABA ABB),则本位可以有:3 + 2 种排法 * * 可以总结出规律,从第 2 位起,就有 3 生 3+2+2,2 生 3+2 的规律 * * 列式: * 假设第一位固定一个,只需要让最后的结果 *3 即可 * f(2) = 3 * f(3) = 3 + 2 + 2 * f(4) = (3 + 2 + 2) + (3 + 2) + (3 + 2) * ………… * 只需要迭代统计 3 出现的次数和 2 出现的次数,计算储结果即可 * * @param n * @return 注意类型可能会超出 int_max */ public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); long n3 = 1, n2 = 0, tmp; while(n-- > 2) { tmp = n3; n3 = tmp + n2; n2 += 2 * tmp; } System.out.println((n3 * 3 + n2 * 2) * 3); } }
package LineCode.Recruit2017.网易;
import java.util.Scanner;
/**
* 题目描述
一个只包含'A'、'B'和'C'的字符串,如果存在某一段长度为3的连续子串中恰好'A'、'B'和'C'各有一个,那么这个字符串就是纯净的,否则这个字符串就是暗黑的。例如:
BAACAACCBAAA 连续子串"CBA"中包含了'A','B','C'各一个,所以是纯净的字符串
AABBCCAABB 不存在一个长度为3的连续子串包含'A','B','C',所以是暗黑的字符串
你的任务就是计算出长度为n的字符串(只包含'A'、'B'和'C'),有多少个是暗黑的字符串。
输入描述:
输入一个整数n,表示字符串长度(1 ≤ n ≤ 30)
输出描述:
输出一个整数表示有多少个暗黑字符串
示例
输入 2 3
输出 9 21
掉的坑:
1.int[] f 不够,要long
*/
public class 暗黑的字符串 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
Integer n = sc.nextInt();
long[] f = new long[n+1];
f[1] = 3;
f[2] = 9;
for (int i = 3; i <= n; i++) {
f[i] = 2 * f[i-1] + f[i-2];
}
System.out.println(f[n]);
}
}
}
//由递推算得通项公式 import java.util.*; public class Main{ public static void main(String[] arg){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); double a = (1 + Math.pow(2,0.5)); double b = 2 - a; double x = (9 - 3 * a)/(b*(b - a)); double y = Math.pow(a,n) * (3-x) + Math.pow(b,n) * x; System.out.print(Math.round(y)); } }