洛谷100题计划(5/100)

洛谷100题计划(5/100)

P1002 [NOIP2002 普及组] 过河卒 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

不开long long见祖宗!!!

把马的控制点都标记,其余正常转移即可

\(dp[i][j] += dp[i - 1][j] + dp[i][j - 1]\)

\(i=0||j=0\)时,只能从左边或者上边转移下来

#include<bits/stdc++.h>

using i64 = long long;

using namespace std;

typedef pair<i64, i64> PII;

i64 dp[24][24];

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int u[] = {0, 1, 2, 2, 1, -1, -2, -2, -1};
    int v[] = {0, -2, -1, 1, 2, 2, 1, -1, -2};

    int xb, yb, xm, ym;
    cin >> xb >> yb >> xm >> ym;

    vector g(24, vector<bool>(24, false));
    for (int i = 0; i < 9; i ++) {
        int dx = u[i] + xm;
        int dy = v[i] + ym;
        if (dx >= 0 && dy >= 0 && dx <= xb && dy <= yb)
            g[dx][dy] = true;
    }

    dp[0][0] = 1;
    for (int i = 0; i <= xb; i ++) {
        for (int j = 0; j <= yb; j ++) {
            if (g[i][j]) continue;
            else if (!i) dp[i][j] += dp[i][j - 1];
            else if (!j) dp[i][j] += dp[i - 1][j];
            else dp[i][j] += dp[i - 1][j] + dp[i][j - 1];
        }
    }

    cout << dp[xb][yb] << '\n';
    return 0;
}

P1003 [NOIP2011 提高组] 铺地毯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

先把所以地毯存起来,然后依次判断,啊,是判断最上面的是哪块地毯,不是被多少地毯覆盖qwq

#include<bits/stdc++.h>

using i64 = long long;

using namespace std;

typedef pair<i64, i64> PII;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    vector<int> a(n), b(n), c(n), d(n);
    for (int i = 0; i < n; i ++)
        cin >> a[i] >> b[i] >> c[i] >> d[i];

    int x, y;
    cin >> x >> y;

    int ans = 0;
    for (int i = 0; i < n; i ++) {
        if (x >= a[i] && y >= b[i] && x <= a[i] + c[i] && y <= b[i] + d[i])
            ans = i + 1;
    }

    if (!ans) cout << "-1\n";
    else cout << ans << '\n';

    return 0;
}

P1008 [NOIP1998 普及组] 三连击 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

因为数据很小,所以我们可以直接暴力排列枚举

#include<bits/stdc++.h>

using i64 = long long;

using namespace std;

typedef pair<i64, i64> PII;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int a[] = {0,1,2,3,4,5,6,7,8,9};
    do{
        int num1 = 0,num2 = 0,num3 = 0;
        num1 = a[1] * 100 + a[2] * 10 + a[3];
        num2 = a[4] * 100 + a[5] * 10 + a[6];
        num3 = a[7] * 100 + a[8] * 10 + a[9];
        if(num1 * 2 == num2 && num1 * 3 == num3)
            cout << num1 << ' ' << num2 << ' ' << num3 << '\n';
    }while(next_permutation(a + 1, a + 1 + 9));

    return 0;
}

P1028 [NOIP2001 普及组] 数的计算 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

考虑\(n\)只有\(1000\),我们可以直接dfs去找答案,但是直接跑会超时,要用记忆化搜索,即记录每个数能得到的合法序列

#include<bits/stdc++.h>

using i64 = long long;

using namespace std;

typedef pair<i64, i64> PII;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;

    vector<int> a(n + 1);
    auto dfs = [&](auto self,int x){
        if(x == 1) return 1;
        if(a[x]) return a[x]; 
        for(int i = 1;i <= (x >> 1);i ++){            
            a[x] += self(self, i);
        }
        return ++a[x];
    };

    cout << dfs(dfs,n) << '\n';
    return 0;
}

P1029 [NOIP2001 普及组] 最大公约数和最小公倍数问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

观察样例其实可以发现答案都是成对出现的,所以我们只需要去枚举一半即可,且可以发现,其实\(P,Q\)都是\(x0 \times y0\)的因子,但我们不需要去枚举他的全部因子,只需要枚举到其中一个,另外一个就可以用\(\frac{x0 \times y0}{i}\)求出来,因此只需要枚举到\(\sqrt{x0 \times y0}\)即可,另外当\(x0 = y0\)时,只有\((x0,y0)\)这一对是符合的,需要特判一下

#include<bits/stdc++.h>

using i64 = long long;

using namespace std;

typedef pair<i64, i64> PII;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int x0, y0;
    cin >> x0 >> y0;

    auto lcm = [](int x, int y) {
        return x / gcd(x, y) * y;
    };

    i64 q = x0 * y0, ans = 0;

    for (int i = 1; i <= sqrt(q); i ++) {
        if (gcd(i, q / i) == x0 && lcm(i, q / i) == y0)
            ans ++;
    }

    if(x0 == y0) cout << 1 << '\n';
    else cout << ans * 2 << '\n';
    return 0;
}
posted @ 2023-08-22 00:42  Ke_scholar  阅读(15)  评论(0编辑  收藏  举报