0x02 递推与递归
Posted kkkstra
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了0x02 递推与递归相关的知识,希望对你有一定的参考价值。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 using namespace std; 7 int n; 8 vector<int> chosen; 9 void calc(int x) 10 if (x==n+1) 11 for (int i=0; i<chosen.size(); ++i) 12 printf("%d ", chosen[i]); 13 cout<<endl; 14 return; 15 16 calc(x+1); 17 chosen.push_back(x); 18 calc(x+1); 19 chosen.pop_back(); 20 21 int main() 22 cin>>n; 23 calc(1); 24 return 0; 25
在前面的基础上加入以下代码即可:
if (chosen.size()>m||chosen.size()+(n-x+1)<m) return;
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 using namespace std; 7 int n, m; 8 vector<int> chosen; 9 void calc(int x) 10 if (chosen.size()>m||chosen.size()+(n-x+1)<m) 11 return; 12 if (x==n+1) 13 for (int i=0; i<chosen.size(); ++i) 14 printf("%d ", chosen[i]); 15 cout<<endl; 16 return; 17 18 chosen.push_back(x); 19 calc(x+1); 20 chosen.pop_back(); 21 calc(x+1); 22 23 int main() 24 cin>>n>>m; 25 calc(1); 26 return 0; 27
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 using namespace std; 7 int n; 8 int order[20]; 9 int chosen[20]; 10 void calc(int k) 11 if (k==n+1) 12 for (int i=1; i<=n; ++i) 13 printf("%d ", order[i]); 14 puts(""); 15 return; 16 17 for (int i=1; i<=n; ++i) 18 if (chosen[i]) continue; 19 order[k]=i; 20 chosen[i]=1; 21 calc(k+1); 22 order[k]=0; 23 chosen[i]=0; 24 25 26 int main() 27 cin>>n; 28 calc(1); 29 return 0; 30
容易发现3个性质:
1.每个位置最多点击一次
2.固定了第一行,满足题意的点击方案只有一种,如第i行已被固定,第i位为1,则第i+1行该位置需要被点击
3.点击先后顺序不影响最终结果
所以用位运算枚举第一行的点击方案,再递推出2~5行的点击,最后判断第5行是否满足题意即可。
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; int g[10][10]; char nex[5][2]=0,0,0,-1,-1,0,1,0,0,1; void turn(int x, int y) for (int i=0; i<5; ++i) int tx=x+nex[i][0]; int ty=y+nex[i][1]; if (tx>0&&tx<=5&&ty>0&&ty<=5) g[tx][ty]^=1; void print() /*for (int i=1; i<=5; ++i) for (int j=1; j<=5; ++j) printf("%1d", g[i][j]); printf("\n"); puts("");*/ int solve() int ans=0x3f3f3f3f; for (int i=0; i<32; ++i) int flag=1, tot=0; int tmp[10][10]; memcpy(tmp, g, sizeof(tmp)); for (int j=0; j<5; ++j) if ((i>>j)&1) //如果第j位为1,则第一排的第j位需要被按一下 turn(1, j+1); tot++; print();/*printf("a\n");*/ for (int j=1; j<5; ++j) for (int k=1; k<=5; ++k) if (g[j][k]==0) turn(j+1, k); tot++; print();/*printf("b\n");*/ for (int j=1; j<=5; ++j) if (g[5][j]==0) flag=0; memcpy(g, tmp, sizeof(g)); if (flag) ans=min(ans, tot); else continue; if (ans>6) return -1; return ans; int main() //freopen("1.txt", "w", stdout); int T; scanf("%d", &T); while (T--) for (int i=1; i<=5; ++i) for (int j=1; j<=5; ++j) scanf("%1d", &g[i][j]); printf("%d\n", solve()); return 0; /* 1 11101 11101 11110 11111 11111 */
以上是关于0x02 递推与递归的主要内容,如果未能解决你的问题,请参考以下文章