牛客 猜数游戏

###题意:
给定一个只包含Y,N的字符串,第i个位置上为Y代表某个数能被i整除,N代表不能,如果存在满足每个字符上的条件的数,则称这个字符串是合法的。
已知字符串长度求合法的字符串的个数,答案模1e9+7。
###思路:

  1. 如果一个数的质因子超过一个则它位置上的字符是被唯一确定的。

如6

如果2,3为NY,YN,NN,则6上的字符为N
如果2,3位YY,则6上的字符为Y

如12

如果4,3为NY,YN,NN,则6上的字符为N
如果4,3位YY,则6上的字符为Y

所以这样的数可以不用考虑。
2. 在就是只包含一个质因子的数。可以按质因子分类,因为包含不同质因子的数不会互相影响,这样就可以用乘法原理计数,而对于只包含一个质因子的数p(对于2来说,就是2,4,8,16,32,64)在n(即题目中给的字符串长度 )范围内的p的幂次加1即为它的变化的情况数。在把每个质数的贡献乘起来即为所求。
###代码:

#include <bits/stdc++.h>
#define pi acos(-1)
#define pb push_back
#define LL long long
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define local freopen("in.txt","r",stdin)
#define input_fast std::ios::sync_with_stdio(false);std::cin.tie(0)
using namespace std;
const int MOD = 1e9 + 7;
const int INF = 0x7FFFFFFF;
const int MAX = 1000000;
inline void read(int& x){
    int flag = 1; char c; while(((c = getchar()) < '0' || c > '9') && c != '-');
    c == '-' ? (flag = -1, x = 0) : (x = c - '0');
    while((c = getchar()) >= '0' && c <= '9') { x = x * 10 + c - '0'; } x *= flag;
}

bool isprime[1000010];

LL solve(int n){
    LL i, j, tmp, cnt, res = 1;

    for(i = 2; i <= n; ++i){
        if(isprime[i]) continue;
        for(j = i * i; j <= n; j += i)
            isprime[j] = true;
        tmp = i; cnt = 0;
        while(tmp <= n){
            ++cnt;
            tmp *= i;
        }
        res = res * (cnt + 1) % MOD;
    }
    return res;
}
int main(){
    int input; LL ans;

    while(~scanf("%d", &input)){
        memset(isprime, 0, sizeof isprime);
        ans = solve(input);
        printf("%I64d\n", ans);
    }
    return 0;
}

###总结:

  1. 这题也是求1到n的最小公倍数的因子个数
  2. 在n的范围内每个质数的幂次即为1到n的最小公倍数。
### 关于二叉树的游戏与练习题 #### 构造二叉树 通过给定的先序遍历 `preorder` 和中序遍历 `inorder` 来构建一棵二叉树是一个经典的算法问题[^1]。此问题的核心在于利用先序遍历的第一个元素作为根节点,并从中序遍历中找到该根节点的位置,从而划分左子树和右子树。 以下是基于 Python 的解决方案: ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def buildTree(preorder, inorder): if not preorder or not inorder: return None root_val = preorder[0] root_index_in_inorder = inorder.index(root_val) root = TreeNode(root_val) root.left = buildTree(preorder[1:root_index_in_inorder + 1], inorder[:root_index_in_inorder]) root.right = buildTree(preorder[root_index_in_inorder + 1:], inorder[root_index_in_inorder + 1:]) return root ``` #### 层序遍历与后续遍历 对于上述构造好的二叉树,可以进一步计算其层序遍历和后续遍历的结果[^2]。需要注意的是,在实际编程环境中(如 C++),由于内存分配的原因可能导致组越界的错误,因此需要合理规划据结构的空间大小。 以下是层序遍历的一个简单实现: ```python from collections import deque def levelOrder(root): result = [] queue = deque([root]) while queue: node = queue.popleft() if node: result.append(node.val) queue.append(node.left) queue.append(node.right) return result ``` #### 子树翻转操作 另一个常见的问题是关于二叉树的镜像翻转。可以通过递归的方式从叶子节点向上逐级反转左右子树来完成整个过程[^3]。 下面是执行这一功能的方法示例: ```python def invertTree(root): if root is None: return None temp = root.left root.left = invertTree(root.right) root.right = invertTree(temp) return root ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值