AcWing 116. 飞行员兄弟
原题链接
简单
作者:
莫争_0
,
2020-03-31 15:36:40
,
所有人可见
,
阅读 2
优化版,利用hamming_weight算法进行剪枝
总时间1134ms。hamming_weight算法可以快速算出整数二进制表示中的1的个数,若当前op的1的个数大于等于已储存的最小值,则continue。
#include<bits/stdc++.h>
using namespace std;
const int N=7;
char g[N][N],backup[N][N];
int hamming_weight(int n) {
n = (n&0x55555555) + ((n>>1)&0x55555555);
n = (n&0x33333333) + ((n>>2)&0x33333333);
n = (n&0x0f0f0f0f) + ((n>>4)&0x0f0f0f0f);
n = (n&0x00ff00ff) + ((n>>8)&0x00ff00ff);
n = (n&0x0000ffff) + ((n>>16)&0x0000ffff);
return n;
}
void turn(int x,int y){
for(int i=0;i<4;i++){
backup[x][i]=backup[x][i]=='+'?'-':'+';
backup[i][y]=backup[i][y]=='+'?'-':'+';
}
backup[x][y]=backup[x][y]=='+'?'-':'+';
}
int main(){
for(int i=0;i<4;i++)cin>>g[i];
int temp=1<<16;
int Min=INT_MAX,Minop=INT_MAX;
for(int op=0;op<temp;op++){
int cnt=hamming_weight(op);
if(cnt>=Min)continue;
memcpy(backup,g,sizeof g);
bool success=true;
for(int i=15;i>=0;i--){
if(op>>i&1)turn((15-i)/4,(15-i)%4);
}
for(int i=0;i<4;i++){
for(int j=0;j<4;j++)
if(backup[i][j]=='+'){
success=false;
break;
}
}
if(success){
Min=cnt;
Minop=op;
}
}
cout<<Min<<endl;
for(int i=15;i>=0;i--){
if(Minop>>i&1){
printf("%d %d\n",(15-i)/4+1,(15-i)%4+1);
}
}
return 0;
}