阿里笔试4月1日,第一题暴力破解,求高效解答
题目:第一行输入整数T, 接下来每行输入一个只有0和1组成的二进制字符串,共输入T个字符串。对于每个字符串,可以翻转每个二进制位若干次,如果能够通过翻转变成全0字符串,输出最少翻转次数,否则输出“NO”;
翻转规则:0变成1,1变成0;翻转第i位时将相邻i-1,i+1的位置字符也翻转(i-1,i+1不能越界)
如:011: 翻转第3位变成000,故输出“1”;
01:输出“NO”
import java.util.*;
public class MyTest{
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int T=Integer.valueOf(scanner.nextLine());
//存放输入的二进制字符串
List<String>input=new ArrayList<>();
//存放结果字符串
List<String>res=new ArrayList<>();
while(T>0 && scanner.hasNextLine()){
input.add(scanner.nextLine());
//初始化为全NO
res.add("NO");
T--;
}
for(int i=0;i<input.size();i++){
String temp=input.get(i);
int len=temp.length();
//全0就不用翻
if(checkAllZeros(temp)){
res.set(i,"0");continue;
}
//记录最小翻转次数
int min_cnt=Integer.MAX_VALUE;
//直接产生一个位翻转序列,(0表示对应的位不翻,1表示翻)0...01开始到1...11结束
//总共有2^len种位翻转序列
char[]zeros=new char[len];
Arrays.fill(zeros,'0');
//二进制字符串前缀0填充至len长度
String prefixZeros=new String(zeros);
//位翻转序列通过j转化为对应的二进制字符串来表示
for(int j=1;j<=Math.pow(2,temp.length())-1;j++){
StringBuilder sb=new StringBuilder(temp);
String sequence=generateSequence(j,len,prefixZeros);
int cnt=0;
for(int p=0;p<len;p++){
if(sequence.charAt(p)=='1'){
sb=convert(sb,p);
cnt++;
}
}
//判断是否满足全0
if(checkAllZeros(sb.toString())){
min_cnt=Math.min(min_cnt,cnt);
}
}
if(min_cnt!=Integer.MAX_VALUE){
res.set(i,String.valueOf(min_cnt));
}
}
for(int i=0;i<res.size();i++){
System.out.println(res.get(i));
}
}
public static String generateSequence(int j,int len,String allZeros){
//将j转换为二进制字符串,长度为len
String s= allZeros+Integer.toBinaryString(j);
return s.substring(s.length()-len,s.length());
}
public static StringBuilder convert(StringBuilder sb,int index){
sb.setCharAt(index,getReverse(sb.charAt(index)));
if(index>0){
sb.setCharAt(index-1,getReverse(sb.charAt(index-1)));
}
if(index<sb.length()-1){
sb.setCharAt(index+1,getReverse(sb.charAt(index+1)));
}
return sb;
}
public static char getReverse(char c){
if(c=='0')return '1';
else return '0';
}
public static boolean checkAllZeros(String s){
for(int i=0;i<s.length();i++)
if(s.charAt(i)=='1')return false;
return true;
}
} 输出测试: 10->'NO'
110-->'1'
101011-->“3” (3-->110111;1-->000111; 5-->000000)
...
#阿里笔试##笔试题目##阿里巴巴#
查看9道真题和解析