您的位置:首页 > 大数据 > 人工智能

2015 Multi-University Training Contest 8

2015-08-18 20:20 615 查看

1004、Too Simple

题目传送:HDU - 5399 - Too Simple

自己在纸上模拟一下,其实可以找到一个规律,也就是找-1的个数n,然后答案为(n-1)*m!(m为每一层的方案数,因为可以任意选)

然后记得没有-1的时候要特判一下

AC代码:

[code]#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代码:

[code]#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: