阿里笔试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)
...
#阿里笔试##笔试题目##阿里巴巴#