#include<bits/stdc++.h> using namespace std; /* dfs(i) 第i個激光機器 有兩種選擇:vis[i-1] == 0 時 可選,不管vis[i-1]爲什麼值都不選 vis[i] 回溯標記是否用過 */ int n = 30; int vis[35]; int ans = 0; int dp[35]; void dfs(int x){ if(x == n+1){ ans++; return; } dfs(x+1); //這個點不開激光 if(vis[x-1] == 0){//前一個點沒開激光 那麼這個點能夠開激光: vis[x] = 1就表示開激光 vis[x] = 1; dfs(x+1); vis[x] = 0;//回溯 } } int main(){ for(int i=1;i<=30;i++) vis[i] = 0; dfs(1); cout<<ans<<endl; return 0; } //2178309
#include<bits/stdc++.h> using namespace std; int n,m; const int maxn = 10; int g[maxn][maxn]; vector<int> v; set<vector<int> > se; set<vector<int> > se2; map<int, int> Hash; int ans = 0; bool check_color() { for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) { if(i+1 <= n && j+1 <= m) { //1 1 1 1 2 2 2 2 1 2 1 2 if((g[i][j]+g[i][j+1]+g[i+1][j]+g[i+1][j+1]) % 4 == 0) return false; } } return true; } bool check2(){ for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(g[i][j] == 0){ return false; } } } for(int i=1;i<=n-1;i++){ for(int j=1;j<=m-1;j++){ int aa = g[i][j]; int bb = g[i+1][j]; int cc = g[i][j+1]; int dd = g[i+1][j+1]; if(aa == bb && aa ==cc && bb== cc && cc == dd && bb == dd && aa == dd){ return false; } } } return true; } bool check(){ for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(g[i][j] == 0){ return false; } } } for(int i=1;i<=n-1;i++){ for(int j=1;j<=m-1;j++){ if(g[i][j] == g[i+1][j] == g[i][j+1] == g[i+1][j+1]) return false; } } return true; } void dfs(int x,int y){ if(x == n+1 && y == 1){ // for(int i=1;i<=n;i++){ // for(int j=1;j<=m;j++){ // cout<<g[i][j]<<" "; // } // cout<<endl; // } if(check_color()){ v.clear(); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ v.push_back(g[i][j]); } } se.insert(v); } if(check2()){ v.clear(); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ v.push_back(g[i][j]); } } se2.insert(v); } return; } if(g[x][y]){ if(y == m) dfs(x+1,1); else dfs(x,y+1); }else{ if(y+1 <= m && !g[x][y+1]){ for(int i=1;i<=2;i++){ g[x][y+1] = i; g[x][y] = i; if(y == m){ dfs(x+1,1); }else{ dfs(x,y+1); } g[x][y] = 0; g[x][y+1] = 0; } } if(x+1 <= n && !g[x+1][y]){ for(int i=1;i<=2;i++){ g[x+1][y] = i; g[x][y] = i; if(y == m){ dfs(x+1,1); }else{ dfs(x,y+1); } g[x+1][y] = 0; g[x][y] = 0; } } } } int main(){ n = 3, m =10; dfs(1,1); cout<<se2.size()<<endl; cout<<se.size()<<endl; set<vector<int> >::iterator it = se2.begin(); vector<int> vv; while(it != se2.end()){ if(se2.find(*it) != se2.end() && se.find(*it) == se.end() ){ vv = *it; break; } it++; } int t = 0; for(int i=0;i<vv.size();i++){ if(t == 10) { t = 0; cout<<endl; } cout<<vv[i]<<" "; t++; } cout<<endl; return 0; } //123996個人答案 check函數 是錯的?!! check2函數是對的 //101466網上答案 是對的!! //緣由:檢查顏色的函數出錯 爲何? 不能連等判斷。。。。。這語法 //已改正 /* 1 1 1 1 1 1 1 1 1 1 1 2 1 2 2 1 2 2 1 2 1 2 2 2 2 2 1 1 1 2 */
#include<bits/stdc++.h> using namespace std; /* 分紅幾組? k組 1 ~ 10; 每組:dfs搜索0~9這幾個沒用過的數; if 徹底平方數 1.x+1 2.繼續加值 (0不能做爲第一個數 單獨考慮) 到了k組 先對結果排序存到vector數組中 再set去重(由於遞歸回溯 結果有大量重複) 注意:必須用long long...用int會出錯 由於int的取值範圍爲:-2147483648 ~ 2147483647 */ typedef long long ll; int vis[15]; ll a[15]; vector<ll> v; int vis2[10]; int k; int ans = 0; set<vector<ll> > se; inline bool check(ll x){ if(x == 9814072356){ int eeeeee = 1; } double d = sqrt(x); return d == (ll)d; } //由於遞歸回溯有大量重複 改爲set去重 void dfs(int x,ll cur){ if(x == k){ for(int i=0;i<10;i++){ vis2[i] = 0; } for(int i=0;i<k;i++){ ll d = a[i]; if(d == 0) vis2[d] = 1; else{ while(d){ vis2[d%10] = 1; d = d/10; } } } for(int i=0;i<=9;i++){ if(!vis2[i]) return; } for(int i=0;i<k;i++) v.push_back(a[i]); sort(v.begin(),v.end()); if(se.find(v) == se.end()){ for(int i=0;i<k;i++) cout<<v[i]<<" "; cout<<endl; se.insert(v); } v.clear(); ans++; return; } for(int i=0;i<=9;i++){ if(!vis[i]){ vis[i] = 1; if(cur == 0 && i == 0){//若是是以0開頭 而且當前搜索的是一個新的分組(cur值爲0) 就直接搜索下一組 a[x] = 0; dfs(x+1,0); vis[i] = 0; continue; } ll num = cur*10+i; if(check(num)){ a[x] = num; dfs(x+1,0); } //搜索下一分組 dfs(x,cur*10+i);//繼續搜索當前分組 vis[i] = 0; } } } int main(){ //freopen("out1.txt","w",stdout); //枚舉分組的次數 for(k = 1;k <= 10;k++){ memset(vis,0,sizeof(vis)); dfs(0,0); } cout<<ans<<endl; cout<<se.size()<<endl; return 0; } //3085 //300
#include<bits/stdc++.h> using namespace std; int n = 47 + 46 + 61;//邊長 int a[19] = {2, 5, 9, 11, 16, 17, 19, 21, 22, 24, 26, 30, 31, 33, 35, 36, 41, 50, 52}; int g[500][500];//大正方形地圖 int vis[30]; set<int> se;//集合存儲正方形最後一行邊長數據結果 void fill(int x,int y,int l,int num){ for(int i=x;i<=x+l-1;i++){ for(int j=y;j<=y+l-1;j++){ g[i][j] = num; } } } bool ok(int x,int y,int l){ if(x+l-1 > n) return false; if(y+l-1 > n) return false; for(int i=x;i<=x+l-1;i++){ for(int j=y;j<=y+l-1;j++){ if(g[i][j] != 0) return false; } } return true; } bool check(){ return true; } void dfs(int x,int y){ if(x == n+1){//遞歸出口 if(check()){ for(int i=1;i<=n;i++){ se.insert(g[n][i]);//set集合存儲最後一層正方形邊長數據 } } return; } if(g[x][y] != 0 ){//當前正方形填充過了 if(y == n) dfs(x+1,1);//dfs下一個 else dfs(x,y+1);//dfs下一個 }else{//當前正方形沒有填充過 for(int i=0;i<19;i++){//枚舉19塊正方形 if(!vis[i]){ if(ok(x,y,a[i])){ fill(x,y,a[i],a[i]);//填充正方造成a[i]邊長 以(x,y)爲左上頂點 vis[i] = 1; if(y == n){ dfs(x+1,1);//dfs下一個 }else{ dfs(x,y+1);//dfs下一個 } vis[i] = 0;//回溯 fill(x,y,a[i],0);//填充正方造成0 以(x,y)爲左上頂點 }else{ break;//剪枝 由於a數組按順序排的 當前邊長不行 後面邊長更不行了 } } } } } int main(){ fill(1,1,47,47);//填充以(1,1)爲左上頂點的正方形 邊爲47 fill(1,47+1,46,46); fill(1,47+46+1,61,61); dfs(1,1);//從(1,1)點開始搜索 set<int>::iterator it = se.begin(); while(it!=se.end()){ cout<<*it<<" "; it++; } return 0; } //30 33 41 50