字符串划分
Description
给定一个由0和1组成的数组A,将数组分成3个非空的部分,使得所有这些部分表示相同的二进制值。
如果可以做到,请返回任何[i, j],其中i+1 < j,这样一来:
A[0], A[1], ..., A[i]组成第一部分;
A[i+1], A[i+2], ..., A[j-1]作为第二部分;
A[j], A[j+1], ..., A[A.length - 1]是第三部分。
这三个部分所表示的二进制值相等。
如果无法做到,就返回[-1, -1]。
注意,在考虑每个部分所表示的二进制时,应当将其看作一个整体。例如,[1,1,0]表示十进制中的6,而不会是3。此外,前导零也是被允许的,所以[0,1,1]和[1,1]表示相同的值。
Input
输入一个只有0和1的字符串A
Output
输出符合题目条件的i和j,中间用空格隔开
Sample Input 1
1 0 1 0 1
Sample Output 1
0 3
Sample Input 2
1 1 0 1 1
Sample Output 2
-1 -1
Hint
3 <= A.length <= 30000
A[i] == 0或A[i] == 1
思路:
1.首先计算这个字符串中1的个数之和cnt
2.要把这个字符串分为3段,因为要求这三段所表示的二进制是相同的,因此就是要求这三段里面的数字1的位置必须是相同的,也就是说有3个相同的二进制数,因此这三段的二进制数就是有3个一样的数,
所以cnt%3==0,(首先保证1的个数在每段里面是相同的);
3.题目要求求i,j,所以我们要把分段的地方给求出来,所以有三个for循环依次用三个不同的变量依次记录第一出现1的下标ans1,cnt/3+1出现1的位置ans2,cnt/3*2+1的位置ans3;
4.然后再用a[ans1]==a[ans2]&&a[ans2]==a[ans3]&&ans<j判断,ans1++,ans2++,asn3++;就是相同就往后移一旦不相同或到了最后就截至
5.输出答案
代码:
#include<stdio.h> #include<string.h> int main(){ char a[60001]; char s[30001]; int cnt = 0; int j = 0; gets(a); for(int i=0;a[i]!='\0';i++){ if(a[i]=='1') cnt++; if(a[i]=='1'||a[i]=='0'){ s[j++] = a[i]; } } printf("%s\n",s); s[j]='\0'; int ans1=0; int ans2=0; int ans3 = 0; if(cnt%3!=0||cnt==0){ printf("-1 -1\n"); } else{ for(int i = 0;s[i]!='\0';i++){ if(s[i]=='1'){ ans1++; if(ans1==1){ ans1 = i; break; } } } for(int i = 0;s[i]!='\0';i++){ if(s[i]=='1'){ ans2++; if(ans2==cnt/3+1){ ans2 = i; break; } } } for(int i=0;s[i]!='\0';i++){ if(s[i]=='1'){ ans3++; if(ans3==cnt/3*2+1){ ans3=i; break;//比赛的时候忘记了 } } } while(s[ans1]==s[ans2]&&s[ans2]==s[ans3]&&ans3<j){ ans1++;ans2++;ans3++; } if(ans3==j) printf("%d %d\n",ans1-1,ans2); else printf("-1 -1\n"); } return 0; }