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; }
相关文章推荐
- 2015 Multi-University Training Contest 9_1007(模拟)
- ResourceManager Main方法
- 数学F - The Snail
- HDU 5319(Painter-暴力)
- hdu 1021 Fibonacci Again
- failed to open gcomm backend connection: 13: error while trying to listen 'tcp:/
- hdu 1867 A + B for you again
- CLI的wait子命令阻塞等待状态更新
- 端口状态说明 LISTENING、ESTABLISHED、TIME_WAIT及CLOSE_WAIT
- 扩展存储过程 xp_smtp_sendmail的安装
- WSAIoctl 的SIO_GET_EXTENSION_FUNCTION_POINTER用法
- 第9章 用内核对象进行线程同步(2)_可等待计时器(WaitableTimer)
- Algorithm negotiation fail 问题解决
- Ubuntu上编译安装Kamailio
- 2015 HUAS Summer Trainning #6~F
- Leetcode#70||Climbing Stairs
- dell 720 raid 配置
- maven Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.10:
- 假设synthesize省略,语义属性声明assign retain copy时间,为了实现自己的setter和getter方法
- Contains Duplicate III