Java刷漆问题代码_Java实现蓝桥杯历届试题格子刷油漆
問題描述
X國的一段古城墻的頂端可以看成 2*N個格子組成的矩形(如下圖所示),現需要把這些格子刷上保護漆。
你可以從任意一個格子刷起,刷完一格,可以移動到和它相鄰的格子(對角相鄰也算數),但不能移動到較遠的格子(因為油漆未干不能踩!)
比如:a d b c e f 就是合格的刷漆順序。
c e f d a b 是另一種合適的方案。
當已知 N 時,求總的方案數。當N較大時,結果會迅速增大,請把結果對 1000000007 (十億零七) 取模。
輸入格式
輸入數據為一個正整數(不大于1000)
輸出格式
輸出數據為一個正整數。
樣例輸入
2
樣例輸出
24
樣例輸入
3
樣例輸出
96
樣例輸入
22
樣例輸出
359635897
問題分析:
首先,對這些墻刷油漆主要分為兩大類:
1.從最邊緣的四個格子出發,然后遍歷完所有格子;
2:從中間的某個格子出發,先遍歷完一邊的格子,回到這個格子所對的格子,然后遍歷另一邊的格子。
所以,我們不妨用兩個數組來表示這兩種情況:
1.a[i]數組表示從最邊緣的四個格子中某個出發,遍歷完長度為i,個數為2i個格子的所有種類數;
2.b[i]數組表示從除了最邊緣的四個格子外的某個中間的格子出發,遍歷完一邊回到所對的格子;
然后,我們來分別分析a[i]和b[i]兩種不同的情況:
1.a[i]第一種情況:先走這個格子(以左上角的格子為例)所對的下面的格子,然后從下面這個格子的位置出發,有兩種走法,分別到第二列的兩個格子,所以第一種情況有:
2a[i-1]種;a[i]第二種情況:(舉例)先從左上角的格子走到第二列某個格子,然后從第二列的格子出發,遍歷完右面所有的格子,再回到第二列格子所對的格子,最后到第一列未遍歷的格子,所以這種情況就是我們定義的b[i];a[i]第三種情況:就是遍歷完一二列的所有格子,從第三列的格子出發,進行遍歷。由于遍歷完一二列的所有格子有四種情況,所以第三種情況為:4a[i-2];
所以,a[i]=2a[i-1]+b[i]+4a[i-2];
2.b[i]的情況:b[i]比較簡單,只有兩種情況,從同一行的格子出發,回到他所對的格子;或者從他對角的格子出發,回到他所對的格子。
所以,b[i]=2*b[i-1];
接下來,就是算總和:
1.四個角:定義sun=4*a[n];
2.設從第i列開始,則前面有i-1列,后面有n-i列。
第i列有兩個格子,這兩個格子所表示的情況數是相同的,所以只需要討論一個。
然后,我們以第i列的上面的格子為例,先遍歷他的左邊,然后遍歷右邊。(回到他所對的格子,遍歷右邊時,又分為兩種情況。從第i+1列上面的格子開始和從下面的格子開始)
即b[i]2a[n-i],化簡得:2*b[i-1]2a[n-i];
同理得:先遍歷右邊,再遍歷左邊為:2*b[n-i]2a[i-1];
然后又因為a[1]=1;a[2]=6;b[1]=1;
import java.util.Scanner;
public class 格子刷油漆 {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
long a[]=new long[n+1];
long b[]=new long[n+1];
long sum;
b[1]=1;
for(int i=2;i<=n;i++){
b[i]=2*b[i-1]%1000000007;
}
a[1]=1;a[2]=6;
for(int i=3;i<=n;i++){
a[i]=(2*a[i-1]+b[i]+4*a[i-2])%1000000007;
}
sum=(4*a[n])%1000000007;
for(int i=2;i
sum+=((8*b[i-1]*a[n-i])%1000000007+(8*b[n-i]*a[i-1])%1000000007)%1000000007;//必須每個項都取余,防止有大于這個數的情況
sum%=1000000007;
}
System.out.println(sum);
}
}
總結
以上是生活随笔為你收集整理的Java刷漆问题代码_Java实现蓝桥杯历届试题格子刷油漆的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java中super可以重新父类么_Ja
- 下一篇: GDI+用PNG图片做半透明异型窗口