方格分割 藍橋杯心得



標題:方格分割

6x6的方格,沿着格子的邊線剪開成兩部分。
要求這兩部分的形狀完全相同。

如圖:p1.png, p2.png, p3.png 就是可行的分割法。

試計算:
包括這3種分法在內,一共有多少種不同的分割方法。
注意:旋轉對稱的屬於同一種分割法。

請提交該整數,不要填寫任何多余的內容或說明文字。


 

一開始想的是按着一個方塊一個方塊搜索,但是沒有考慮到dfs只能是一筆畫!!!所以樣例的所有情況都沒考慮到下面是我比賽的時候寫的代碼(知道結果的時候還是比較傷心的,花了大把的時間最后還是入坑了  哎  還是有待鍛煉啊~~!!!):

<↓↓↓這個代碼是錯的哦!!!只是本人比賽時寫的~~可以略過>

 1 #include<stdio.h>
 2 #include<math.h>
 3 #include<ctype.h>
 4 #include<string.h>
 5 #include<stdlib.h>
 6 
 7 int aa[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
 8 int line[10][10];
 9 struct data {
10     int dis[6][6];
11 }vis[10000];
12 int sum;
13 void dfs(int x,int y,int n)
14 {
15     n++;
16     int i,j;
17     if(n>=18){
18         for(i=0;i<6;i++){
19             for(j=0;j<6;j++){
20                 vis[sum].dis[i][j]=line[i][j];
21                 //printf("%d ",line[i][j]);
22             }
23             //printf("\n");
24         }
25         //system("pause");
26         sum++;
27         return ;
28     }
29     int a,b;
30     for(i=0;i<4;i++){
31         a=x+aa[i][0];
32         b=y+aa[i][1];
33         if(a>=0&&a<6&&b>=0&&b<6&&line[a][b]==-1){
34             line[a][b]=1;
35             line[5-a][5-b]=0;
36             dfs(a,b,n);
37             line[a][b]=-1;
38             line[5-a][5-b]=-1;
39         }
40     }
41     return ;
42 }
43 int main ()
44 {
45     memset(line,-1,sizeof(line));
46     sum=0;
47     line[0][0]=1;
48     line[5][5]=0;
49     dfs(0,0,0);
50     int i,j,k,l,num=0;
51     for(i=0;i<sum;i++){
52         int yy=0;
53         for(j=i+1;j<sum;j++){
54             int y=1;
55             for(k=0;k<6;k++){
56                 for(l=0;l<6;l++){
57                     if(vis[i].dis[k][l]!=vis[j].dis[k][l]){
58                         y=0;
59                         break;
60                     }
61                 }
62                 if(y==0)
63                     break;
64             }
65             if(y==1){
66                 yy=1;
67                 break;
68             }
69         }
70         if(yy==0){
71             for(k=0;k<6;k++){
72                 for(l=0;l<6;l++){
73                     printf("%d ",vis[i].dis[k][l]);
74                 }
75                 printf("\n");
76             }
77             system("pause");
78             num++;
79         }
80     }
81     printf("%d %d %d\n",sum,num,num/2);//sum為所有搜到的結果,num是去重之后的結果,因為num里面還沒有考慮到左下和右上對稱的情況,所以最后結果應對二取商
82     return 0;
83 }//最后結果是:45

 

后來在網上看到一個大牛寫的解題報告,思路主要就是搜索他的切割線,把他的每種情況的切割線搜出來,雖然方塊不是一筆畫,但是他的切割線肯定是一個一筆畫啊(一刀兩快兒

),而且每一種切割線都會經過中間的那個點(肯定啊!!(3,3)和(4,4)肯定不在同一個塊兒里面啊~~~所以切割線肯定會經過他們相鄰的那個點),切割線應該從中點開始搜索,而且只要搜索到邊線(就是已經把方塊分成兩部分了)就可以結束,從中點開始搜第一步有四個方向,而且任意一個方向反轉一下都可以得到另一個方向的所有情況,所以使用邊線搜索的結果最后應該除以/4,下面是從網上搜到的代碼:出自http://blog.csdn.net/y1196645376/article/details/69718192/

 1 #include <algorithm>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <stdio.h>
 5 #include <string>
 6 #include <vector>
 7 #include <queue>
 8 #include <map>
 9 #include <set>
10 using namespace std;
11 const int N = 6;
12 int ans = 0;
13 int mpt[N+1][N+1];
14 int dir[4][2] = {0,1,1,0,0,-1,-1,0};
15 void dfs(int x,int y)
16 {
17     if(x == 0 || y == 0 || x == N || y == N){
18         int i,j;
19         ans ++;
20         return;
21     }
22     for(int i = 0 ; i < 4 ; i ++)
23     {
24         int tx = x + dir[i][0];
25         int ty = y + dir[i][1];
26         if(mpt[tx][ty])continue;
27         mpt[tx][ty] = 1;
28         mpt[N-tx][N-ty] = 1;
29         dfs(tx,ty);
30         mpt[tx][ty] = 0;
31         mpt[N-tx][N-ty] = 0;
32     }
33 }
34 int main()
35 {
36     mpt[N/2][N/2] = 1;
37     dfs(N/2,N/2);
38     printf("%d\n",ans/4);
39     return 0;
40 }最后結果 509

但是看到這個代碼之后呢,感覺還是有點問題,從中點開始搜索,有四個方向,最后結果除以四,但是在每一個方向里面也會有一些對稱的啊例如下圖啊假設一開始的時候從中心的點往右走,就可以得到這兩種一不同的分割線(所以感覺還是有問題的,有待更新吧,也許是我考慮的東西多了吧):

     

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM