再戦を設定し、問題への2012年のNOIPユニバーサルソリューション

トピックカバーアルゴリズム:

  • 素因数分解:はじめに。
  • トレジャーハント:シミュレーション。
  • 置か花:動的計画。
  • 文化ツアー:検索。

の素因数分解

トピックのリンクは:https://www.luogu.org/problem/P1075
この質問はループのためだけ開いている本を探し出すことができるようになります。
2からオープンループ変数iは、n個の割り切れるI、出力の最初の出会いをジャークを開始されました\(N / Iが\) その後破ります。
次のようにコードは次のとおりです。

#include <bits/stdc++.h>
using namespace std;
int n;
int main() {
    cin >> n;
    for (int i = 2; ; i ++) if (n % i == 0) { cout << n / i << endl; break; }
    return 0;
}

トレジャーハント

トピックリンク:https://www.luogu.org/problem/P1076を
標準のシミュレーションの質問、プロセスについては、部屋の登山をシミュレートすることができます。
しかし、私の言語は、この質問は読むのに長い時間のために読み込まれ、良いではありません。
あなたは原理は、サイクルの除去を探して保持されていない最適化、最適化することができます。
次のようにコードは次のとおりです。

#include <bits/stdc++.h>
using namespace std;
const int MOD = 20123;
int n, m, has_key[10010][110], num[10010][110], sum[10010], id, ans;
int main() {
    cin >> n >> m;
    for (int i = 0; i < n; i ++)
        for (int j = 0; j < m; j ++) {
            cin >> has_key[i][j] >> num[i][j];
            if (has_key[i][j]) sum[i] ++;
        }
    cin >> id;
    for (int i = 0; i < n; i ++) {
        int cnt = 0;
        int x = num[i][id] % sum[i];
        if (x == 0) x = sum[i];
        ans = (ans + num[i][id]) % MOD;
        while (true) {
            if (has_key[i][id]) {
                cnt ++;
                if (cnt == x) break;
            }
            id = (id + 1) % m;
        }
    }
    cout << ans << endl;
    return 0;
}

置か花

トピックリンク:https://www.luogu.org/problem/P1077
この質問は、動的計画法によって解決されます。
私たちは、状態にする([I] [J fは\は \]) フロント示し\(私は\)花が合計入れ\(J \) その後、数スキーム流域を

  • \(F [0] [0] = 0 \)
  • \(F [I] [J] = \ sum_ {k = 0} ^ {\分([I]、j)は} \ [k]は[I-1] F)

次のようにコードは次のとおりです。

#include <bits/stdc++.h>
using namespace std;
const int MOD = 1000007;
const int maxn = 110;
int n, m, a[maxn], f[maxn][maxn];
int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i ++) cin >> a[i];
    f[0][0] = 1;
    for (int i = 1; i <= n; i ++)
        for (int j = 0; j <= m; j ++)
            for (int k = 0; k <= a[i] && j-k >= 0; k ++)
                f[i][j] = (f[i][j] + f[i-1][j-k]) % MOD;
    cout << f[n][m] << endl;
    return 0;
}

文化ツアー

トピックリンク:https://www.luogu.org/problem/P1078
建てマップ、条件付きの深さ優先探索。
この質問は、データの目的は、より多くの水であってもよいので、私は恥ずかしい1,000以上の私はないと判断うステップ数を見つけることが、その後、AC〜という条件を追加しました。
次のようにコードは次のとおりです。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;
int N, K, M, S, T, d = INT_MAX, c[maxn], a[maxn][maxn], u, v, w;
bool vis[maxn];
vector< pair<int, int> > g[maxn];
void dfs(int u, int tmp) {
    if (tmp >= 1000) return;    // 没想到这样就AC了~~~
    if (tmp >= d) return;
    if (u == T) {
        d = tmp;
        return;
    }
    vis[ c[u] ] = true;
    int sz = g[u].size();
    for (int i = 0; i < sz; i ++) {
        int v = g[u][i].first;
        int w = g[u][i].second;
        if (vis[ c[v] ] ) continue;
        bool flag = true;
        for (int i = 1; i <= K; i ++) {
            if (vis[i] && a[ c[v] ][i]) {
                flag = false;
                break;
            }
        }
        if (flag) {
            dfs(v, tmp+w);
        }
    }
    vis[ c[u] ] = false;
}
int main() {
    cin >> N >> K >> M >> S >> T;
    for (int i = 1; i <= N; i ++) cin >> c[i];
    for (int i = 1; i <= K; i ++)
        for (int j = 1; j <= K; j ++)
            cin >> a[i][j];
    while (M --) {
        cin >> u >> v >> w;
        g[u].push_back( make_pair(v, w) );
        g[v].push_back( make_pair(u, w) );
    }
    dfs(S, 0);
    if (d == INT_MAX) d = -1;
    cout << d << endl;
    return 0;
}

おすすめ

転載: www.cnblogs.com/codedecision/p/11741738.html