本文共 1819 字,大约阅读时间需要 6 分钟。
为了解决这个问题,我们需要判断是否可以从左下角走到右上角,经过的正方形大小相同,并且只能向上或向右走。我们需要高效地处理大数范围,并确保计算不会溢出。
问题分析:
关键观察:
算法选择:
复杂度分析:
#includeusing namespace std;ll pow2(int x) { return static_cast (1 << x);}ll sum1(int i) { return (pow2(i + 1) - 2) - i;}ll sum2(int m) { ll res = 0; for (int j = 1; j <= m; ++j) { res += pow2(2 * (j - 1)); } return res;}int main() { int t; scanf("%d", &t); while (t--) { ll n, k; scanf("%lld%lld", &n, &k); if (n >= 32) { printf("YES %lld\n", n - 1); continue; } ll sum1_n = sum1(n); bool flag = false; int temp; for (int i = 1; i <= n; ++i) { ll s = sum1(i); if (s > k) continue; int m = n - i; ll t_sum = sum2(m); ll power = pow2(i + 1) - 1; ll t = t_sum * power; ll target = sum1_n - t; if (k <= target && k >= s) { flag = true; temp = i; break; } } if (flag) { printf("YES %d\n", temp); } else { printf("NO\n"); } } return 0;}
函数定义:
pow2(int x)
计算 (2^x)。sum1(int i)
计算路径上的分割次数。sum2(int m)
计算总分割次数。主函数:
遍历逻辑:
该方法高效地处理了大数范围,并确保了计算的正确性和效率。
转载地址:http://fuml.baihongyu.com/