十字架

题目链接: http://exercise.acmcoder.com/online/online_judge_ques?ques_id=3373&konwledgeId=40

解题思路: 可以看出边长和n的关系,L=pow(3,n-1)。当n=10时,整个图形的大小就是3^18那么大,对于内存来说有点大。所以,我们想办法去递推每一行的情况。

我们可以把一个图形分成分成9块。

块1 块2 块3
块4 块5 块6
块7 块8 块9

根据题目的要求,块2,4,5,6,8就都是一个L'=pow(3,n-2)的图形,剩下的部分都是空格。

所以我们可以得到每个位置的递推公式。令L=pow(3,n-1),L1=L/3,L2=2*L1;

块2: i<=L1, L1<j<=L2, pos(i,j,n) = pow(i,j-L1,n-1)

块4: L1<i<=L2, j<=L1, pos(i,j,n)=pow(i-L1,j,n-1)

块5,6,8是类似的。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 const int MAXN=100005;
 6 const LL MON7 = 1e9+7;
 7 
 8 char deduce(int i,int j, int n)
 9 {
10     if (n==1 && i==1 && j==1) return 'o';
11     int L=pow(3,n-1);
12     int L1=L/3;
13     int L2=L1*2;
14     if (i<=L1)
15     {
16         if (j<=L1 || j > L2) return ' ';
17         return deduce(i,j-L1,n-1);
18     }
19     if (i<=L2)
20     {
21         if (j<=L1) return deduce(i-L1,j,n-1);
22         if (j<=L2) return deduce(i-L1,j-L1,n-1);
23         return deduce(i-L1,j-L2,n-1);
24     }
25     if (j<=L1 || j>L2) return ' ';
26     return deduce(i-L2,j-L1,n-1);
27 }
28 
29 char s[MAXN];
30 int n;
31 
32 void solve()
33 {
34     int L=pow(3,n-1);
35     for (int i=1;i<=L;++i)
36     {
37         for (int j=1;j<=L;++j)
38         {
39             s[j]=deduce(i,j,n);
40         }
41         s[L+1]='\0';
42         printf("%s\n",s+1);
43     }
44 }
45 
46 int main()
47 {
48 #ifndef ONLINE_JUDGE
49     freopen("test.txt","r",stdin);
50 #endif // ONLINE_JUDGE
51     int Case;
52     int tCase=0;
53     scanf("%d",&Case);
54     while (Case--)
55     {
56         scanf("%d",&n);
57         printf("Case #%d:\n", ++tCase);
58         solve();
59     }
60     return 0;
61 }

 

posted @ 2018-04-24 21:44  只会一点暴力  阅读(209)  评论(0编辑  收藏  举报