爬格子呀--一堆东西
来源:互联网 发布:电脑音乐剪辑软件 编辑:程序博客网 时间:2024/04/30 23:16
好久没上传了,主要是因为期中考试的复习,没有足够的时间来写
期中考试大物不及格,但是数学建模校赛却拿到了二等奖,塞翁失马吧
好几道题这次是,发现越来越难了,但却好像又有规律可循
代码如下:
Uva1343旋转游戏
#include<cstdio>#include<cmath>#include<algorithm>using namespace std;int a[24];char ans[10000];//表格的线性化/* 00 01 02 0304 05 06 07 08 09 10 11 1213 14 15 16 17 18 19 20 21 22 23*/int mat[8][7] = { { 0,2,6,11,15,20,22 },//A 0 { 1,3,8,12,17,21,23 },//B 1 { 10,9,8,7,6,5,4 },//C 2 { 19,18,17,16,15,14,13 },//D 3 { 23,21,17,12,8,3,1 },//E 4 { 22,20,15,11,6,2,0 },//F 5 { 13,14,15,16,17,18,19 },//G 6 { 4,5,6,7,8,9,10 },//H 7};int center[8] = { 6,7,8,11,12,15,16,17 };//判断是否达到最终情况bool tar() { for (int i = 0; i < 8; i++) if (a[center[i]] != a[center[0]]) return false; return true;}//寻找1、2、3三个数在中圈中的数值与目标不一样的个数,数量越小,表示1、2、3在中圈中的个数越多int time(int k) { int ans = 0; for (int i = 0; i < 8; i++) { if (a[center[i]] != k) ans++; } return ans;}//寻找最小值int find_min() { return min(min(time(1), time(2)), time(3));}//移动棋盘序列void move(int i) { int mid = a[mat[i][0]]; int j = 0; for (; j < 6; j++) { a[mat[i][j]] = a[mat[i][j + 1]]; } a[mat[i][6]] = mid;}//dfs建立在递归的基础上//这个dfs用到了IDA*的算法进行剪枝,d为深度,maxd为目标上限find_min为乐观估价函数,与深度相加判断是否越界bool dfs(int d, int maxd) { //与dfs类似,优先判断是否满足条件 if (tar()) { for (int i = 0; i < d; i++) { putchar(ans[i]); } //ans[d] = '\0'; //printf("%s\n", ans); return true; } //IDA*的判断 if (d + find_min() > maxd) return false; int t[24];// memcpy(t, a, sizeof(a)); for (int i = 0; i < 8; i++) { ans[d] = 'A' + i; //这一步的ans[d]很关键,因为d只有在这一次迭代成功的时候才会改变 //这就保证了可以通过循环来深度遍历,并且不断的更新 move(i); if (dfs(d + 1,maxd)) return true; //若失败,则清除上面的移动 //memcpy(a, t, sizeof(a)); int mid = (i + 4) % 8; mid % 2 == 0 ? move(mid + 1) : move(mid - 1); } return false;}int main() { while (scanf("%d",&a[0]), a[0]!=0) { for (int i = 1; i < 24; i++) scanf("%d", &a[i]); if (tar()) printf("No moves needed"); else for (int maxd = 1; ; maxd++) if (dfs(0,maxd)); break; printf("%d", a[center[0]]); } return 0;}
Uva818–切断圆环链
#include<cstdio>#include<iostream>#include<algorithm>#include<deque>#include<utility>using namespace std;typedef pair<int, int> p;const int maxn = 15;int node, n, t;deque<p>store[maxn + 1];bool can_find(int i, p pp) { for (deque<p>::iterator it=store[i].begin();it!=store[i].end(); advance(it,1)) if ((*it).first == pp.first) { if (it == store[i].begin()) { store[i].push_front(make_pair(pp.second, pp.first)); return true; } node++; store[++t].push_back(pp); return true; } return false;}int main() { p pp; scanf("%d", &n); scanf("%d %d", &pp.first, &pp.second); store[t].push_back(pp); while (n != 0) { scanf("%d %d", &pp.first, &pp.second); if (pp.first == -1 && pp.second == -1) break; for (int i = 0; i <= t; i++) { int size = store[i].size(); if (size == 0) { store[i].push_back(pp); break; } //判断能否插入到末尾 if (store[i][size - 1].second == pp.first) { store[i].push_back(pp); //判断是否为大环 if (store[i][0].first == pp.second) { node++; t++; break; } break; } //判断是否为一环套多环 else if (can_find(i, pp)) break; } } printf("%d", node); return 0;}
Uva1602–网格动物
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<set>using namespace std;const int maxn = 10;int n, w, h;int dir[4][2] = { { 0,1 },{ 0,-1 },{ 1,0 },{ -1,0 } };struct cell { int x, y; cell(int x = 0, int y = 0) :x(x), y(y) {};//函数包含默认构涵,可以显示的构造自己想要的特定结构体 bool operator < (const cell &rhs)const { return x < rhs.x || (x == rhs.x && y < rhs.y); }};#define FOR_CELL(c,p) for(set<cell>::const_iterator c=(p).begin();c!=(p).end();c++)//规范化,根据书上面讲的,应该是想通过做差值来减少运算量???inline set<cell> normalize(const set<cell>&p) { int minx = p.begin()->x, miny = p.begin()->y; FOR_CELL(c, p) { minx = min(minx, c->x); miny = min(miny, c->y); } set<cell>pp; FOR_CELL(c, p) { pp.insert(cell(c->x - minx, c->y - miny)); } return pp;}//旋转,坐标运算inline set<cell> rotate(const set<cell>&p) { set<cell>pp; FOR_CELL(c, p) { pp.insert(cell(c->y, -c->x)); } return normalize(pp);}//对称,坐标运算inline set<cell> flip(const set<cell>&p) { set<cell>pp; FOR_CELL(c, p) { pp.insert(cell(c->x, -c->y)); } return normalize(pp);}set<set<cell>>poly[maxn + 1];int ans[maxn + 1][maxn + 1][maxn + 1];//三维数组,表示三个限定条件下的结果,这个是提前计算的需要//检查,如果点new_cell无法通过p中已有的点的坐标变化得到,就说明p是一个新的点,将其加入到点集中void check(const set<cell>& p, const cell &new_cell) { set<cell>pp = p; pp.insert(new_cell); pp = normalize(pp); int n = pp.size(); for (int i = 0; i < 4; i++) { if (poly[n].count(pp) != 0) return; pp = rotate(pp); } pp = flip(pp); for (int j = 0; j < 4; j++) { if (poly[n].count(pp) != 0) return; pp = rotate(pp); } poly[n].insert(pp);}//计算函数void generate() { set<cell>s; s.insert(cell(0, 0)); poly[1].insert(s); //网格多边形从1开始 for (int n = 2; n <= maxn; n++) { for (set<set<cell>>::iterator p = poly[n - 1].begin(); p != poly[n - 1].end(); p++) { FOR_CELL(c, *p) for (int i = 0; i < 4; i++) { cell new_cell(c->x + dir[i][0], c->y + dir[i][1]); if (p->count(new_cell) == 0) check(*p, new_cell); } } } //提前计算,逆回归过程 for (int n = 1; n <= maxn; n++) for (int w = 1; w <= maxn; w++) for (int h = 1; h <= maxn; h++) { int num = 0; for (set<set<cell>>::iterator p = poly[n].begin(); p != poly[n].end(); p++) { int maxx = 0, maxy = 0; FOR_CELL(c, *p) { maxx = max(maxx, c->x); maxy = max(maxy, c->y); } if (min(maxx, maxy) < min(w, h) && max(maxx, maxy) < max(w, h)) num++; } ans[n][w][h] = num; }}int main() { generate(); while (scanf_s("%d%d%d", &n, &w, &h) == 3) { printf("%d\n", ans[n][w][h]); } return 0;}
Uva11214–守卫棋盘(八皇后改版)
#include<cstdio>#include<iostream>#include<string>#include<memory.h>using namespace std;int map[15][15], vis[4][15];int kase, maxn, m, n;bool check() { for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (map[i][j] && !vis[0][i] && !vis[1][j] && !vis[2][i + j] && !vis[3][n - i + j]) return false; } } return true;}bool dfs(int cur,int d,int ma_xn) { if (d == ma_xn) { if (check()) { printf("Case %d: %d\n", ++kase, d); return true; } return false; } for (int i = cur; i < n*m; i++) { int x = i / m, y = i%m; int midx = vis[0][x], midy = vis[1][y], mid_d1 = vis[2][x + y], mid_d2 = vis[3][n - x + y]; vis[0][x] = vis[1][y] = vis[2][x + y] = vis[3][n - x + y] = 1; if (dfs(i, d + 1, ma_xn)) return true; vis[0][x] = midx, vis[1][y] = midy, vis[2][x + y] = mid_d1, vis[3][n - x + y] = mid_d2; } return false;}int main() { while (scanf("%d", &n) && n) { scanf("%d", &m); char s[15]; memset(map, 0, sizeof(map)); for (int i = 0; i < n; i++) { scanf("%s", s); for (int j = 0; j < m; j++) { if (s[j] == 'X') map[i][j] = 1; } } for(maxn=0;;maxn++){ memset(vis, 0, sizeof(vis)); if (dfs(0, 0, maxn)) break; } } return 0;}
Uva817–数字表达式
#include<cstdio>#include<iostream>#include<string>#include<stack>#include<deque>using namespace std;char symbol[4] = { '*','+','-',' ' };char num[20], sign[20];int kase, amount, len;int num2[20];deque<int>tar, ans;bool ok() { //tar储存数字,notation储存符号; int len2 = strlen(sign); int mid, i, j; for (i = len2 - 1, mid = 0; i >= 0; i--) { if (!isdigit(sign[i])) { mid = 0; tar.push_front(mid); continue; } mid = mid * 10 + num[i] - '0'; } deque<int>::iterator it = tar.begin(); for (i = 0; i < strlen(sign); i++) { if (!isdigit(sign[i])) { if (sign[i] == '*') { tar[i] *= tar[i + 1]; advance(it, i + 1); tar.erase(it); it = tar.begin(); } else if (sign[i] == '+') { tar[i] += tar[i + 1]; advance(it, i + 1); tar.erase(it); it = tar.begin(); } else { tar[i] -= tar[i + 1]; advance(it, i + 1); tar.erase(it); it = tar.begin(); } } else continue; } if (tar[0] == 2000) { for (i = 0; i < tar.size()-1; i++) { char *pp = (char*)&tar[i]; ans.push_back(*pp); ans.push_back(sign[i]); } char *pp = (char*)&tar[i]; ans.push_back(*pp); return true; } else return false;}void dfs(int d) { if (d + 2 == len) { if (ok()) printf(" %s=\n", ans), amount++; return; } for (int i = 0; i < 4; i++) { sign[d] = symbol[i]; dfs(d + 1); }}int main() { while (scanf("%s", num) == 1 && num[0] != '=') { memset(sign, '0', sizeof(sign)); amount = 0; len = strlen(num); for (int i = 0; i < len - 2; i++) num2[i] = num[i] - '0'; dfs(0); printf("Problem %d", ++kase); if (!amount) printf("IMPOSSIBLE"); } return 0;}
Uva12107–数字谜
//copy from liudongbohehe#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>using namespace std;char s[3][6];int len[3], maxd;char change[12] = "*0123456789";bool check_result() { char check_str[12]; char ss[12]; int t0 = 0, t1 = 0, t2; for (int i = 0; i < len[0]; i++) t0 = t0 * 10 + s[0][i] - '0'; for (int i = 0; i < len[1]; i++) t1 = t1 * 10 + s[1][i] - '0'; t2 = t0*t1; //上面计算出t2之后,这一步是用t2对check_str[]进行一个逆向的填充 for (int i = 0; i < len[2]; i++) { check_str[len[2] - i - 1] = t2 % 10 + '0';//先填充高位的方法 t2 /= 10; } //检查是否t2被除尽以及首字符是否为0 if (t2 != 0 || check_str[0] == '0') return 0; for (int i = 0; i < len[2]; i++) if (check_str[i] != s[2][i] && s[2][i] != '*') return 0; return 1;}//这个检查其实也是一个dfsint check(int a, int b) { int flag = 0; if (a == 2) return check_result(); int ta, tb; char ch = s[a][b]; if (len[a] - 1 == b) { ta = a + 1; tb = 0; } else { ta = a; tb = b + 1; } if (s[a][b] == '*') { for (int i = 1; i < 11; i++) { if (b == 0 && i == 1) continue; s[a][b] = change[i]; flag += check(ta, tb); if (flag > 1) break; } } else flag += check(ta, tb); s[a][b] = ch; return flag;}//dfs+IDA*bool dfs(int a, int b, int d, int max_d) { int flag = 0; //如果深度等于阈值,则进行判断 if (d == max_d) { if (check(0, 0)==1) return true; else return false; } if (a == 3) return false; int ta, tb; //tmp保存数值,dfs每次迭代的对象是目标数组中的每个元素 char tmp = s[a][b]; if (b == len[a] - 1) { ta = a + 1; tb = 0; } else { ta = a; tb = b + 1; } //依次枚举 for (int i = 0; i < 11; i++) { if (b == 0 && i == 1) continue; if (tmp == change[i]) {//判断是否需要替换数字 s[a][b] = tmp; flag = dfs(ta, tb, d, max_d);//没有换数字所以没有进行深度的叠加 } else { s[a][b] = change[i]; flag = dfs(ta, tb, d + 1, max_d); } if (flag) break; } if (!flag)//没有找到,迭代失败,归还原值 s[a][b] = tmp; return flag;}int main() { int kase=0; memset(s, '0', sizeof(s)); while (1) { scanf("%s", s[0]); if (s[0][0] == '0') break; scanf(" %s %s", s[1], s[2]); for (int i = 0; i < 3; i++) len[i] = strlen(s[i]); //maxd = 0; for (maxd = 0;; maxd++) { //IDA* if (dfs(0, 0, 0, maxd)) break; } printf("Case %d: %s %s %s\n", ++kase, s[0], s[1], s[2]); memset(s, '\0', sizeof(s)); } return 0;}
Uva690–流水线调度
//copy from xuli#include<cstdio>#include<iostream>#include<string>#include<memory.h>#include<algorithm>using namespace std;int n, ans, ndis;int table[5], dis[24];string str;void dfs(int t[5], int d, int len) { if (d == 10) { ans = min(len, ans); return; } if (len + dis[0] * (10 - d) >= ans) return; for (int i = 0; i < ndis; i++) { int tmpdis = dis[i]; bool flag = true; for (int j = 0; j < 5; j++) { if ((t[j] >> tmpdis)&table[j]) flag = false; } if (!flag) continue; int tmpt[5]; for (int j = 0; j < 5; j++) tmpt[j] = (t[j] >> tmpdis) | table[j]; dfs(tmpt, d + 1, len + tmpdis); } return;}int main() { while (scanf("%d",&n) && n) { memset(table, 0, sizeof(table)); for (int i = 0; i < 5; i++) { cin >> str; for (int j = 0; j < n; j++) { if (str[j] == 'X') { table[i] |= (1 << j); } } } ans = n * 10; ndis = 0; bool b; for (int i = 1; i <= n; i++) { b = true; for (int j = 0; j < 5; j++) { if (table[j] & (table[j] >> i)) b = false; } if (b) dis[ndis++] = i; } dfs(table, 1, n); printf("%d", ans); } return 0;}
Uva12113–重叠的正方形
#include<stdio.h>#include<iostream>#include<string.h>#include<memory.h>using namespace std;//string ini[5], tar[5];char ini[10][15], tar[10][15];int vis[9];bool dfs(int cur) { bool flag = false; for (int i = 0; i < 5; i++) { for (int j = 0; j < 9; j++) { if (ini[i][j] != tar[i][j]) { flag = true; break; } } if (flag) break; } if (!flag) return true; if (cur >= 6) return false; char save[10][15]; memcpy(save, ini, sizeof(ini)); for (int i = 0; i < 9; i++) { if (!vis[i]) { int r = i / 3, c = (i % 3) * 2 + 1; ini[r][c] = ini[r][c + 2] = ini[r + 2][c] = ini[r + 2][c + 2] = '_'; ini[r + 1][c - 1] = ini[r + 2][c - 1] = ini[r + 1][c + 3] = ini[r + 2][c + 3] = '|'; ini[r + 1][c] = ini[r + 1][c + 1] = ini[r + 2][c + 1] = ini[r + 1][c + 2] = ' '; vis[i] = 1; if (dfs(cur + 1)) return true; memcpy(ini, save, sizeof(save)); vis[i] = 0; } } return false;}int main() { int kase = 0; while (1) { memset(tar, 0, sizeof(tar)); scanf("%c", &tar[0][0]); if (tar[0][0] == '0') break; for(int i=1;i<9;i++) scanf("%c", &tar[0][i]); getchar(); getchar(); for (int i = 1; i < 5; i++) { for (int j = 0; j < 9; j++) { scanf("%c", &tar[i][j]); } getchar(); getchar(); } memset(ini, ' ', sizeof(ini)); memset(vis, 0, sizeof(vis)); printf("Case %d: ", ++kase); if (dfs(0)) printf("Yes\n"); else printf("No\n"); } return 0;}
继续加油~~
阅读全文
0 0
- 爬格子呀--一堆东西
- 爬格子呀4-1
- 爬格子呀4-2
- 爬格子呀4-3
- 爬格子呀4-4
- 爬格子呀4-5
- 爬格子呀4-8
- 爬格子呀--2048
- 爬格子呀5-1
- 爬格子呀5-2
- 爬格子呀5-3
- 爬格子呀5-4
- 爬格子呀5-5
- 爬格子呀5-6
- 爬格子呀5-7
- 爬格子呀5-8
- 爬格子呀5-10
- 爬格子呀7-1
- php数据类型
- 程序员工资多高才算高?
- CocoaPods删除已安装的库
- shiro 学习日记1
- 抓包工具
- 爬格子呀--一堆东西
- 第5章 初始化与清理
- PHP预定义接口之ArrayAccess
- 多元函数带 Peano余项的Taylor公式的推广 (无参考资料)
- 读书笔记:《小米生态链战地笔记》
- kubernetes 服务发现和负载均衡
- Gradle build running 很慢,甚至卡主
- MongoDB 分片的原理、搭建、应用
- 732. My Calendar III