網站首頁 編程語言 正文
日歷拼圖C++解法
0.介紹
任何一個日期都可以用8塊拼圖拼起來。
如12月3日:
1.思路
主要的思想就是深度優先搜索。
a) 用字符串數組存8種拼圖塊
char a[9][5][5]={ {{'.','.','.','.'}, {'.','.','.','.'}, {'.','.','.','.'}, {'.','.','.','.'}}, {{'1','1','1','1'}, {'1','.','.','.'}, {'.','.','.','.'}, {'.','.','.','.'}}, {{'2','2','2','.'}, {'2','2','.','.'}, {'.','.','.','.'}, {'.','.','.','.'}}, {{'3','3','.','.'}, {'.','3','3','3'}, {'.','.','.','.'}, {'.','.','.','.'}}, {{'4','.','.','.'}, {'4','4','4','.'}, {'.','.','4','.'}, {'.','.','.','.'}}, {{'5','5','5','.'}, {'5','.','.','.'}, {'5','.','.','.'}, {'.','.','.','.'}}, {{'6','6','6','6'}, {'.','6','.','.'}, {'.','.','.','.'}, {'.','.','.','.'}}, {{'7','7','7','.'}, {'7','7','7','.'}, {'.','.','.','.'}, {'.','.','.','.'}}, {{'8','8','8','.'}, {'8','.','8','.'}, {'.','.','.','.'}, {'.','.','.','.'}}};
b) 獲得8種拼圖塊的8種放置方式
這里我使用旋轉加翻轉實現的。
[2] 最開始為第一個,然后翻轉得到第二個。
[3] 再翻轉回來,再順時針90度得到第三個。
重復[2] [3] 步驟就可以得到8種放置方式。
翻轉代碼
也就是左右交換。
void filp(char a[5][5]){ for(int i=0;i<4;i++) for(int j=0;j<2;j++){ swap(a[i][j],a[i][3-j]); } }
旋轉代碼
這里我是順時針旋轉90度。
void rot(char a[5][5]){ char b[5][5]; for(int i=0;i<4;i++){ for(int j=0;j<4;j++) b[i][j] = a[3-j][i]; } for(int i=0;i<4;i++) for(int j=0;j<4;j++) a[i][j] = b[i][j]; }
c) 判斷某一個位置是否可以放置對應的拼圖塊。
這里我們以左上角第一個非.
的位置為起點,然后進行判斷。
bool candown(int x,int y,int i,int j){ int sx = -1, sy = -1; for(int xx=0;xx<4;xx++) for(int yy=0;yy<4;yy++){ if(b[i][j][xx][yy] != '.'){ sx = xx; sy = yy; int kx =sx,ky= sy; while(kx<4 && ky<4){ int nx = x + kx-sx; int ny = y + ky-sy; //如果要覆蓋 if(b[i][j][kx][ky]!='.'){ if(nx<0 || ny<0) return false; if(nx<2 && ny<=5){ if(mp[nx][ny]!='.') return false; // mp[nx][ny] = b[i][j][kx][ky]; } else if(nx<=5 && nx>=2 && ny<=6){ if(mp[nx][ny]!='.') return false; // mp[nx][ny] = b[i][j][kx][ky]; } else if(nx==6 && ny<=2){ if(mp[nx][ny]!='.') return false; // mp[nx][ny] = b[i][j][kx][ky]; } else return false; } if(ky==3){ kx++,ky=0; } else ky++; } return true; } } return false; }
d) 放置拼圖塊
與第c 步類似。
void down(int x,int y,int i,int j){ for(int xx=0;xx<4;xx++) for(int yy=0;yy<4;yy++){ if(b[i][j][xx][yy] != '.'){ int kx =xx,ky= yy; while(kx<4 && ky<4){ int nx = x + kx-xx; int ny = y + ky-yy; if(b[i][j][kx][ky]!='.'){ mp[nx][ny] = b[i][j][kx][ky]; } if(ky==3){ kx++,ky=0; } else ky++; } return; } } }
e) 回溯放置
與 d 步類似。
void undown(int x,int y,int i,int j){ for(int xx=0;xx<4;xx++) for(int yy=0;yy<4;yy++){ if(b[i][j][xx][yy] != '.'){ int kx =xx,ky= yy; while(kx<4 && ky<4){ int nx = x + kx-xx; int ny = y + ky-yy; if(b[i][j][kx][ky]!='.'){ mp[nx][ny] = '.'; } if(ky==3){ kx++,ky=0; } else ky++; } return; } } }
f) 深度優先搜索dfs
這里我用一維代替二維坐標,然后dfs的時候求出對應的位置。
然后就是簡單帶回溯的搜索了。
void dfs(int id){ int x = id/7; int y = id%7; if(x<2 && y==6){ dfs(id+1); } if(x==6 && y==3){ // printf("Success!\n"); for(int i=0;i<7;i++){ for(int j=0;j<7;j++){ if(mp[i][j]=='.') continue; putchar(mp[i][j]); } putchar('\n'); } exit(0); } if(mp[x][y]!='.') dfs(id+1); for(int i=1;i<=8;i++){ if(!vis[i]){ for(int j=1;j<=8;j++){ if(candown(x,y,i,j)){ down(x,y,i,j); vis[i] = 1; dfs(id+1); undown(x,y,i,j); vis[i] = 0; } } } } }
2.完整程序
我這里找到解就退出,如果想要找到每個解的所有情況,可以自行修改代碼。即對應dfs里的exit(0) 去掉。
#includeusing namespace std; typedef long long ll; typedef unsigned long long ull; const int N=1e3+5,M=2e8+5,inf=0x3f3f3f3f,mod=1e9+7; const int hashmod[8] = {802653189,805306857,1610612781,998288353}; #define mst(a,b) memset(a,b,sizeof a) #define db double #define PII pair #define PLL pair #define x first #define y second #define pb emplace_back #define SZ(a) (int)a.size() #define rep(i,a,b) for(int i=a;i<=b;++i) #define per(i,a,b) for(int i=a;i>=b;--i) #define IOS ios::sync_with_stdio(false),cin.tie(nullptr) void Print(int *a,int n){ for(int i=1;i //x=max(x,y) x=min(x,y) void cmx(T &x,T y){ if(x void cmn(T &x,T y){ if(x>y) x=y; } char a[9][5][5]={ {{'.','.','.','.'}, {'.','.','.','.'}, {'.','.','.','.'}, {'.','.','.','.'}}, {{'1','1','1','1'}, {'1','.','.','.'}, {'.','.','.','.'}, {'.','.','.','.'}}, {{'2','2','2','.'}, {'2','2','.','.'}, {'.','.','.','.'}, {'.','.','.','.'}}, {{'3','3','.','.'}, {'.','3','3','3'}, {'.','.','.','.'}, {'.','.','.','.'}}, {{'4','.','.','.'}, {'4','4','4','.'}, {'.','.','4','.'}, {'.','.','.','.'}}, {{'5','5','5','.'}, {'5','.','.','.'}, {'5','.','.','.'}, {'.','.','.','.'}}, {{'6','6','6','6'}, {'.','6','.','.'}, {'.','.','.','.'}, {'.','.','.','.'}}, {{'7','7','7','.'}, {'7','7','7','.'}, {'.','.','.','.'}, {'.','.','.','.'}}, {{'8','8','8','.'}, {'8','.','8','.'}, {'.','.','.','.'}, {'.','.','.','.'}}}; char b[9][9][5][5]; void filp(char a[5][5]){ for(int i=0;i<4;i++) for(int j=0;j<2;j++){ swap(a[i][j],a[i][3-j]); } } void pr(char a[5][5]){ for(int i=0;i<4;i++) { for(int j=0;j<4;j++){ putchar(a[i][j]); } putchar('\n'); } } void rot(char a[5][5]){ char b[5][5]; for(int i=0;i<4;i++){ for(int j=0;j<4;j++) b[i][j] = a[3-j][i]; } for(int i=0;i<4;i++) for(int j=0;j<4;j++) a[i][j] = b[i][j]; } char mp[8][8]={ ".......", ".......", ".......", ".......", ".......", ".......", ".......", }; void cp(char a[5][5],char b[5][5]){ for(int i=0;i<4;i++){ for(int j=0;j<4;j++) a[i][j] = b[i][j]; a[i][4]='\0'; } } int vis[9]; bool candown(int x,int y,int i,int j){ int sx = -1, sy = -1; for(int xx=0;xx<4;xx++) for(int yy=0;yy<4;yy++){ if(b[i][j][xx][yy] != '.'){ sx = xx; sy = yy; int kx =sx,ky= sy; while(kx<4 && ky<4){ int nx = x + kx-sx; int ny = y + ky-sy; //如果要覆蓋 if(b[i][j][kx][ky]!='.'){ if(nx<0 || ny<0) return false; if(nx<2 && ny<=5){ if(mp[nx][ny]!='.') return false; // mp[nx][ny] = b[i][j][kx][ky]; } else if(nx<=5 && nx>=2 && ny<=6){ if(mp[nx][ny]!='.') return false; // mp[nx][ny] = b[i][j][kx][ky]; } else if(nx==6 && ny<=2){ if(mp[nx][ny]!='.') return false; // mp[nx][ny] = b[i][j][kx][ky]; } else return false; } if(ky==3){ kx++,ky=0; } else ky++; } return true; } } return false; } void down(int x,int y,int i,int j){ for(int xx=0;xx<4;xx++) for(int yy=0;yy<4;yy++){ if(b[i][j][xx][yy] != '.'){ int kx =xx,ky= yy; while(kx<4 && ky<4){ int nx = x + kx-xx; int ny = y + ky-yy; if(b[i][j][kx][ky]!='.'){ mp[nx][ny] = b[i][j][kx][ky]; } if(ky==3){ kx++,ky=0; } else ky++; } return; } } } void undown(int x,int y,int i,int j){ for(int xx=0;xx<4;xx++) for(int yy=0;yy<4;yy++){ if(b[i][j][xx][yy] != '.'){ int kx =xx,ky= yy; while(kx<4 && ky<4){ int nx = x + kx-xx; int ny = y + ky-yy; if(b[i][j][kx][ky]!='.'){ mp[nx][ny] = '.'; } if(ky==3){ kx++,ky=0; } else ky++; } return; } } } void dfs(int id){ int x = id/7; int y = id%7; if(x<2 && y==6){ dfs(id+1); } if(x==6 && y==3){ // printf("Success!\n"); for(int i=0;i<7;i++){ for(int j=0;j<7;j++){ if(mp[i][j]=='.') continue; putchar(mp[i][j]); } putchar('\n'); } exit(0); } if(mp[x][y]!='.') dfs(id+1); for(int i=1;i<=8;i++){ if(!vis[i]){ for(int j=1;j<=8;j++){ if(candown(x,y,i,j)){ down(x,y,i,j); vis[i] = 1; dfs(id+1); undown(x,y,i,j); vis[i] = 0; } } } } } int main(){ int m,d; scanf("%d%d",&m,&d); //初始化 mp[m>6][(m-1)%6] = '0'; mp[((d-1)/7)+2][(d-1)%7] = '0'; //得到每個拼圖的所有情況 for(int i=1;i<=8;i++){ cp(b[i][1],a[i]);filp(a[i]); cp(b[i][2],a[i]);filp(a[i]);rot(a[i]); cp(b[i][3],a[i]);filp(a[i]); cp(b[i][4],a[i]);filp(a[i]);rot(a[i]); cp(b[i][5],a[i]);filp(a[i]); cp(b[i][6],a[i]);filp(a[i]);rot(a[i]); cp(b[i][7],a[i]);filp(a[i]); cp(b[i][8],a[i]); } dfs(0); return 0; }
總結
原文鏈接:https://blog.csdn.net/weixin_45750972/article/details/123051047
相關推薦
- 2022-05-11 python?DataFrame數據格式化(設置小數位數,百分比,千分位分隔符)_python
- 2022-06-17 Python實現一維插值方法的示例代碼_python
- 2023-03-02 docker-compose安裝RabbitMQ及插件操作步驟_docker
- 2022-10-06 詳解hive常見表結構_數據庫其它
- 2022-11-01 go語言中for?range使用方法及避坑指南_Golang
- 2022-04-16 論文查重python文本相似性計算simhash源碼_python
- 2022-10-18 Go項目怎么使用枚舉_Golang
- 2022-10-02 Redis進行相關優化詳解_Redis
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支