这一题其实很简单,只是要想到正确方法
我一开始用了奇怪的搜索
①无解的情况:
看上去很离奇,实际上略加思索就会发现,如果输入 \(n\) 为偶数,那么就铁定无解。证明过程如下:
令 \(n\bmod{2}=0\),人距离 \(n\) 点的距离为 \(dis\) ,则当走出第一步(步长为 \(1\))时,有:
\[dis=\mid n\pm1\mid \]所以:
\[dis\bmod{i} = 1 \]设 \(k\) 为正整数且满足 $k > 1 $ ,显然有:
\[2^k \bmod{2}=0 \]因此,在走出第一步后无论怎么走也到达不了奇数的距离,即无法走到 \(n\) 点。
②有解的情况
似乎是一道走路问题,实际上我们可以把向左走看成减法,把向右走看成加法,那么题目就转化成了:
有一个正整数 \(n\),试回答 \(n\) 是否满足如下式子:
\[n=\star2^0\star2^1\star......\star2^k \]如果不满足,则输出 \(-1\),否则输出 \(k\) \((k\in N_+)\),其中"\(\star\)"处可以填正号或负号使式子成立
那么我们观察数据,手算几个,就可以发现:
\[1=2^0 \]\[3=2^0+2^1 \]\[5=-2^0+2^1+2^2 \]\[...... \]规律很难找,但是我们发现不管怎么样,都有 $n\le\mid\star20\mid+\mid\star21\mid+......+\mid\star2^k\mid \(, ("\)\star\("意义如上所述),这其实很好解释,因为如果不满足这个关系式,那么就算"\)\star$"处全部使用正号,也无法达到 \(n\) 的值。
所以我们便可以利用这个特性,让一个变量 \(tot\) 每次累加 \(2^i\) ,直到 \(tot\ge n\),此时累加的次数就是答案。
CODE(这里提供三份代码):
def main():
T = int(input())
for k in range(T + 1):
n = int(input())
if not (n & 1):
print(-1)
continue
tot = 0
for i in range(0, 114514):
tot += (1 << i)
if tot >= n:
print(i + 1)
#注意这里由于i从0开始,所以输出i+1
break
if __name__ == '__main__':
main()
#include <stdio.h>
int main() {
int T, n, tot = 0;
scanf("%d", &T);
while(T --) {
scanf("%d", &n);
if(! (n & 1)) {
printf("-1\n");
continue;
}
for(int i = 0; ; i += 1) {
tot += (1 << i);
if(tot >= n) {
printf("%d\n", i + 1);
break;
}
}
tot = 0;
}
return 0;
}
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int T, n;
int tot = 0;
signed main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> T;
while(T --) {
cin >> n;
if(! (n & 1)) {
cout << -1 << endl;
continue;
}
for(int i = 0; ; i ++) {
tot += (1 << i);
if(tot >= n) {
cout << i + 1 << endl;
break;
}
}
tot = 0;
}
return 0;
}
标签:__,R5,洛谷,int,题解,mid,tot,star2,main
From: https://www.cnblogs.com/ZyIOLO/p/17279970.html