十字架
题目链接: 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 }