HDU 1220 B

http://acm.hdu.edu.cn/showproblem.php?pid=1220

一开始的做法是,先暴力算出一个面,就是n * n的面,能有多少对。记作face

然后从上开始算下来,最上一层,face个,然后第二层,有n * n * (up - 1)个。

递推下去,up是在第i层上面有多少个。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
#define MY "H:/CodeBlocks/project/CompareTwoFile/DataMy.txt", "w", stdout
#define ANS "H:/CodeBlocks/project/CompareTwoFile/DataAns.txt", "w", stdout


#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 1e3 + 20;
int e[maxn][maxn];
int a[maxn][maxn];
int tonext[5][2] = {{0, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 0}};
int n;
void work() {
    int to = 0;
    memset(e, 0, sizeof e);
    memset(a, 0, sizeof a);
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            a[i][j] = ++to;
        }
    }
//    for (int i = 1; i <= n; ++i) {
//        for (int j = 1; j <= n; ++j) {
//            cout << a[i][j] << " ";
//        }
//        cout << endl;
//    }
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            int t = ans;
            for (int k = 1; k <= n; ++k) {
                for (int h = 1; h <= n; ++h) {
                    bool flag = true;
                    if (e[a[i][j]][a[k][h]]) continue;
                    for (int oo = 0; oo < 5; ++oo) {
                        int tx = i + tonext[oo][0];
                        int ty = j + tonext[oo][1];
                        if (k == tx && h == ty) {
                            int dis = abs(a[tx][ty] - a[i][j]);
                            if (dis == 1 || dis == n || dis == 0) {
                                flag = false;
                                break;
                            }
                        }
                    }
                    if (!flag) continue;

                    e[a[i][j]][a[k][h]] = e[a[k][h]][a[i][j]] = 1;
                    ans++;
                }
            }
////            cout << ans - t << " ";
        }
//        cout << endl;
    }
//    cout << ans << endl;
    int per = n * n * n;
    int toans = ans;
    int up = n * n;
    for (int i = 2; i <= n; ++i) {
        toans += ans;
        toans += (n * n) * (up - 1);
        up += n * n;
    }
    cout << toans << endl;
}

int main() {
#ifdef local
    freopen("data.txt","r",stdin);
#endif
    IOS;
    while (cin >> n) work();
    return 0;
}
View Code

逆向思维。

一共有C(n * n * n, 2)对。然后减去4个面的。

一行有n - 1对4个面的,有n行,同样,有n列。然后还有n竖,所以是三种。

每一种,在一个面上,有(n - 1) * n,一个体上,有(n - 1) * n * n,所以减去3 * all

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
#define MY "H:/CodeBlocks/project/CompareTwoFile/DataMy.txt", "w", stdout
#define ANS "H:/CodeBlocks/project/CompareTwoFile/DataAns.txt", "w", stdout


#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
int C(int n, int m) {
    int ans = 1;
    for (int i = 1; i <= m; ++i) {
        ans = ans * (n - i + 1) / i;
    }
    return ans;
}
int n;
void work() {
    cout << C(n * n * n, 2) - (n - 1) * n * n * 3 << endl;
}

int main() {
#ifdef local
    freopen("data.txt","r",stdin);
#endif
    IOS;
    while (cin >> n) work();
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6098287.html