链接:https://ac.nowcoder.com/acm/contest/272/A
来源:牛客网
题目描述
给出v, k,请你找到最小的正整数n,满足:
n的二进制表示下存在一个长度为v的回文串,该回文串首尾都是1且n的二进制表示中至少有k个1。保证v,k均为偶数!
由于n可能很大,你只需要输出对取模的结果。输入描述:
两个整数v, k。保证v,k均为偶数!输出描述:
一个整数,表示n对取模的结果。示例1
输入
6 4输出
45说明
样例的构造方法为:101101示例2
输入
2 4输出
15说明
最优的构造方法为:1111备注:
。
思路:先找符合条件的二进制串,再转换为十进制。
1,当v>=k,二进制越短对应的十进制就越小,所以让整个二进制串都是回文串,想让数最小,就要从中间向两边添1来构造二进制串
2,v<k,就让二进制串都是1
二进制转换为十进制应该这样写:
long long ans=0;
for(int i=1;i<=v;i++)
{
ans=(ans*2+a[i])%mod;
}
printf("%lld\n",ans);
我太菜了,一面对结果很大需要取余mod的,就不知道怎么写,下面是错误代码(还不知道为啥错。。。好菜啊。。)
long long sum=0;
for(int i=1,j=v-1;i<=v,j>=0;i++,j--)
sum+=(a[i]*(long long)pow(2,j)+mod)%mod;// double pow(diuble x,double y)返回的是double型
printf("%lld\n",(sum+mod)%mod);
AC代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
const int maxn=1e5+7;
int a[maxn],b[maxn];
int main()
{
int v,k;
int mod=1e9+7;
scanf("%d%d",&v,&k);
if(k<=v)//从中间向两边添1
{
a[1]=1;
for(int i=2;i<=v/2;i++)
{
if(i>=v/2-k/2+2)
a[i]=1;
else
a[i]=0;
}
int count=0;
for(int i=v/2+1;i<v;i++)
{
if(count<k/2-1)
{
a[i]=1;
count++;
}
else
a[i]=0;
}
a[v]=1;
}
else//k>v时,应为k个1
{
for(int i=1;i<=k;i++)
a[i]=1;
v=k;
}
//二进制转换为十进制
long long ans=0;
for(int i=1;i<=v;i++)
{
ans=(ans*2+a[i])%mod;
}
printf("%lld\n",ans);
return 0;
}