题目:
翻译:
思路:
1、由题目可知,他想让我们判断交换相邻字符位置后将二进制转为十进制后,能否整除2的次方。能整除即输出需要交换的次数,不能则输出-1。(例:输入3和010这组数据就要判断能否整除2、4、8这三个数。)
2、两个子函数:一个将字符串转为代表的十进制数;另一个进行将相邻字符互换位置。
3、详细见代码中注释。
代码:
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int ans = 0;
long long judge(string s,int n)//二进制转十进制
{
long long sum = 0;
for (int i = 0; i < n; i++)
{
if (s[i] == '1')
sum += pow(2, i);
}
return sum;
}
int zhuanhuan(string& s)//交换位置
{
int a = s.find("1",0);//查找第一个1的位置
int flag = 1;//标记
while (flag)
{
if (a == s.size() - 1)
return 0;//满了
if (s[a + 1] == '0')//前一位为0,则交换位置
{
swap(s[a + 1], s[a]);
ans++;//交换次数加一
flag = 0;
}
else//不为零往前一位
a++;
}
return 1;
}
int main()
{
int n;
cin >> n;//输入数据组数
while (n--)
{
string s;
ans = 0;
int t;
cin >> t;//字符个数
cin >> s;//输入字符串
reverse(s.begin(), s.end());//翻转字符串
int k = 1;//整除数从2的一次方开始
for (int k = 1; k <= t; k++)
{
long long a = pow(2, k);//该2的次方
int flag = 1;
while (flag)
{
if (judge(s, t) % a == 0)可以整除该2的次方
{
cout << ans << " ";//输出转化次数
break;
}
flag = zhuanhuan(s);//转换一次,返回的为0,即不能转换了,达到最大值
}
if (flag == 0)//输出-1
cout << "-1 ";
}
cout << endl;
}
}
结果: