2015 Multi-University Training Contest 8



1004、Too Simple

題目傳送:HDU - 5399 - Too Simple

自己在紙上模擬一下,其實可以找到一個規律,也就是找-1的個數n,然後答案爲(n-1)*m!(m爲每一層的方案數,因爲可以任意選)

然後記得沒有-1的時候要特判一下

AC代碼:

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <sstream>
#include <utility>
#include <iostream>
#include <algorithm>
#include <functional>
#define LL long long
#define INF 0x7fffffff
using namespace std;

#define MOD 1000000007

int n, m;

map<int, int> mp;

LL jie[105];

int a[105][105];

void init() {
    jie[0] = 1;
    for(int i = 1; i < 105; i ++) {
        jie[i] = (jie[i-1] * i) % MOD;
    }
}

LL get_pow(int x, int n) {
    LL ret = 1;
    for(int i = 0; i < n; i ++) {
        ret = ret * jie[x] % MOD;
    }
    return ret;
}

bool fun(int m, int x, int p) {
    if(m == 1) {
        if(a[m][x] == p) return true;
        else return false;
    }
    return fun(m-1, a[m][x], p);
}

int main() {
    init();
    //for(int i = 1; i<= 10; i ++) cout << jie[i] << " ";
    while(scanf("%d %d", &n, &m) != EOF) {
        int t;
        int flag = 0;
        int c = 0;
        //int cnt = 0;
        LL ans = 1;
        for(int i = 1; i <= m; i ++) {
            //cout << ans << endl;
            mp.clear();
            scanf("%d", &a[i][1]);
            mp[a[i][1]] = 1;
            if(a[i][1] != -1) {
                //ans = (ans * get_pow(n, cnt-1)) % MOD;
                //cnt = 0;
                for(int j = 2; j <= n; j ++) {
                    scanf("%d", &a[i][j]);
                    if(mp[a[i][j]] == 1) {
                        flag = 1;
                    }
                    mp[a[i][j]] = 1;
                }
            }
            else {
                //cnt ++;
                c ++;
            }
        }
        ans = (ans * get_pow(n, c - 1)) % MOD;
        int flag2 = 0;
        if(c == 0) {
            for(int i = 1; i <= n; i ++) {
                if(!fun(m, i, i)) {
                    flag2 = 1;
                    break;
                }
            }
        }
        //cout << flag << " " << flag2 << endl; 
        if(flag == 1 || flag2 == 1) {
            printf("0\n");
        }
        else printf("%I64d\n", ans);
    }
    return 0;
}



1007、Travelling Salesman Problem

題目傳送:HDU - 5402 - Travelling Salesman Problem

官方題解:

首先如果n爲奇數或者m爲奇數,那麼顯然可以遍歷整個棋盤。

如果n,m都爲偶數,那麼將棋盤黑白染色,假設(1,1)和(n,m)都爲黑色,那麼這條路徑中黑格個數比白格個數多11,而棋盤中黑白格子個數相同,所以必然有一個白格不會被經過,所以選擇白格中權值最小的不經過。

構造方法是這樣,首先RRRRDLLLLD這樣的路徑走到這個格子所在行或者上一行,然後DRUR這樣走到這個格子的所在列或者前一列,然後繞過這個格子。然後走完這兩行,接着按LLLLDRRRR這樣的路徑往下走。

這裏要注意必定需要走一個白格的情況,所以只需要不走那個權值最小的,按照不走權值最小的那個結點構造即可。

AC代碼:

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <sstream>
#include <utility>
#include <iostream>
#include <algorithm>
#include <functional>
#define LL long long
#define INF 0x7fffffff
using namespace std;

int mp[105][105];
int vis[105][105];
int n, m;

const int dx[] = {1, -1, 0, 0};
const int dy[] = {0, 0, 1, -1};

int main() {
    while(scanf("%d %d", &n, &m) != EOF) {
        int sum = 0;
        int minx = INF, mini, minj;
        for(int i = 1; i <= n; i ++) {
            for(int j = 1; j <= m; j ++) {
                scanf("%d", &mp[i][j]);
                sum += mp[i][j];
                if((i + j) & 1) {
                    if(minx > mp[i][j]) {
                        minx = mp[i][j];
                        mini = i;
                        minj = j;
                    }
                }
            }
        }
        string ans;
        ans.clear();
        if((n & 1) || (m & 1)) {
            printf("%d\n", sum);
            if(n & 1) {
                int i, j;
                for(i = 1; i <= n; i ++) {
                    for(j = 1; j < m; j ++) {
                        if(i & 1) ans += "R";
                        else ans += "L";
                    }
                    if(i != n) ans += "D";
                }
            }
            else {
                int i, j;
                for(i = 1; i <= m; i ++) {
                    for(j = 1; j < n; j ++) {
                        if(i & 1) ans += "D";
                        else ans += "U";
                    }
                    if(i != m) ans += "R";
                }
            }
            printf("%s\n", ans.c_str());
            continue;
        }

        //cout << mini << " " << minj << endl;
        memset(vis, 0, sizeof(vis));
        printf("%d\n", sum - minx);
        int i = 1, j = 1;//行和列
        while(1) {
            if(i == mini || i == mini - 1) break;
            for(j = 1; j < m; j ++) {
                if(i & 1) ans += "R";
                else ans += "L";
            }
            if(i < n) ans += "D";
            i ++;
        }
        if(i & 1) j = 1;
        else j = m;

        vis[i][j] = 1;
        int bu = 2 * m - 2;
        //cout << i << " " << j << endl;
        int L = 1, R = m, U = i, D = i + 1;
        while(bu --) {
            for(int k = 0; k < 4; k ++) {
                int x = i + dx[k];
                int y = j + dy[k];
                if(!vis[x][y] && x <= D && x >= U && y <= R && y >= L && !(x == mini && y == minj)) {
                    if(k == 0) ans += "D";
                    else if(k == 1) ans += "U";
                    else if(k == 2) ans += "R";
                    else if(k == 3) ans += "L";
                    vis[x][y] = 1;
                    i = x, j = y;
                    break;
                }
            }
        }
        //ans += " ";
        i ++;
        //cout << "hha" << endl;
        if(i <= n) ans += "D";
        while(i <= n) {
            for(j = 1; j < m; j ++) {
                if(i & 1) ans += "L";
                else ans += "R";    
            }
            if(i != n) ans += "D";
            i ++;
        }
        printf("%s\n", ans.c_str());
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章