LuoguB2133 我家的门牌号 题解

Update

  • \(\texttt{2021.11.27}\) 修复了代码中的 \(10000\) 写成 \(n\) 的错误。

Content

一个家庭住在一个胡同里面,门牌号从 \(1\) 开始编号。其余门牌号的和减去这个家庭的门牌号的两倍恰好等于 \(n\),求这个家庭的门牌号和胡同的门牌号总数。

数据范围:\(n<10^5\)。

Solution

如果设胡同的门牌号总数为 \(m\),并设这个家庭的门牌号为 \(k\),则由题意可得(其中 \([i\neq k]\) 表示如果 \(i\neq k\),则这个值为 \(1\),否则为 \(0\)):

\[\sum\limits_{i=1}^mi[i\neq k]-2k=n \]

如果我们把这个 \(\sum\limits_{i=1}^mi[i\neq k]\) 转化一下:

\[\begin{aligned}1+2+\dots+k-1+k+1+\dots+m&=1+2+\dots+m-k\\&=\sum\limits_{i=1}^mi-k\end{aligned} \]

所以:

\[\begin{aligned}\sum\limits_{i=1}^mi-k-2k&=n\\3k&=\sum\limits_{i=1}^mi-n\\k&=\dfrac{\sum\limits_{i=1}^mi-n}{3}\end{aligned} \]

用等差数列求和公式将 \(\sum\limits_{i=1}^mi\) 转化为 \(\dfrac{m(m+1)}2\) 可得:

\[k=\dfrac{\dfrac{m(m+1)}2-n}3 \]

因此,我们可以枚举 \(m\),然后是否满足以下两个条件:

  • \(\dfrac{m(m+1)}2>n\)。
  • \(3\mid(\dfrac{m(m+1)}2-n)\)(表示 \(3\) 能整除 \(\dfrac{m(m+1)}2-n\))。

可以发现,一旦满足了以上两个条件,\(m\) 此时的值依然很小,因此这样枚举是可以通过这道题的。

Code

#include <cstdio>
using namespace std;

int main() {
    int n; scanf("%d", &n);
    for(int i = 1; i <= 10000; ++i) {
        int ans = i * (i + 1) / 2;
        if(ans > n && !((ans - n) % 3)) {printf("%d %d", (ans - n) / 3, i); return 0;}
    }
    return 0;
}
上一篇:论文解读(LLE)《Nonlinear Dimensionality Reduction by Locally Linear Embedding》and LLE


下一篇:SP4491 PGCD - Primes in GCD Table