1.求一个n序列的所有子集。
二进制做法:
#include <iostream> using namespace std; int n; void print(int n,int s)//输出子集s包含的元素 { for(int i=0;i<n;i++) { //<<把一个整型数的所有位向左移动指定的位数,移动到左边界之外的多余二进制位会被丢弃,并从右边界移入0 if(s&(1<<i))//从最右侧开始遍历s中是否含有相应的元素 cout << i+1 << " "; } cout << endl; } int main() { cin>>n; for(int i=0;i<(1<<n);i++)//设置二进制数的长度,枚举子集 print(n,i); return 0; }
2.在中国象棋中,马是走日字的。一个马的管辖范围指的是当前位置以及一步之内能走到的位置,下图的绿色旗子表示马能走到的位置。
如果一匹马的某个方向被蹩马脚,它就不能往这个方向跳了,如下图所示,海星的位置存在旗子,马就不能往上跳到那两个位置了:
那么问题来了,在一个 n×m 的棋盘内,如何用最少的马管辖住所有n×m 个格子。比如 n=m=3 时,最少要用 5 只马才能管辖所有棋盘,一种可能的方案如下:
当 n=m=5时,请你求出用最少马管辖的方案个数。
思路:用二进制。暴力所有的情况。
代码:
#include<stdio.h> #include<string.h> #include<queue> #include<iostream> #include<math.h> #include<algorithm> using namespace std; typedef long long ll; ll a[210110],n; int book[26]; int s[6][6]; ll sum; int to[4][2]= {1,0,0,1,-1,0,0,-1}; int h[8][2]= {2,1, 1,2, -1,-2, -2,-1, 1,-2, -2,1, -1,2, 2,-1}; int pan() { int vis[9][9]= {0}; int tag=0; for(int i=1; i<=5; i++) { for(int j=1; j<=5; j++) { if(s[i][j]==1) { tag++; vis[i][j]=1; if(s[i-1][j]==0) { int x1=i-2; int y1=j-1; int x2=i-2; int y2=j+1; if(x1>=1&&y1>=1&&x1<=5&&y1<=5) vis[x1][y1]=1; if(x2>=1&&y2>=1&&x2<=5&&y2<=5) vis[x2][y2]=1; } if(s[i+1][j]==0) { int x1=i+2; int y1=j-1; int x2=i+2; int y2=j+1; if(x1>=1&&y1>=1&&x1<=5&&y1<=5) vis[x1][y1]=1; if(x2>=1&&y2>=1&&x2<=5&&y2<=5) vis[x2][y2]=1; } if(s[i][j-1]==0) { int x1=i-1; int y1=j-2; int x2=i+1; int y2=j-2; if(x1>=1&&y1>=1&&x1<=5&&y1<=5) vis[x1][y1]=1; if(x2>=1&&y2>=1&&x2<=5&&y2<=5) vis[x2][y2]=1; } if(s[i][j+1]==0) { int x1=i-1; int y1=j+2; int x2=i+1; int y2=j+2; if(x1>=1&&y1>=1&&x1<=5&&y1<=5) vis[x1][y1]=1; if(x2>=1&&y2>=1&&x2<=5&&y2<=5) vis[x2][y2]=1; } } } } int flag=0; for(int i=1; i<=5; i++) { for(int j=1; j<=5; j++) { if(vis[i][j]==0) {flag=1;break;} } if(flag)break; } if(!flag)book[tag]++; } int main() { ll n=1<<25; memset(book,0,sizeof(book)); for(int i=1; i<n; i++) { memset(s,0,sizeof(s)); for(int j=0; j<25; j++) { if(i&(1<<j)) { int x=(j/5)+1; int y=(j%5)+1; s[x][y]=1; } } pan(); } for(int i=0;i<=25;i++){ if(book[i]) { printf("%d %d\n",i,book[i]); break; } } }