POJ 1753 Flip Game
“很好很有层次感”题单的第一题。 题意是黑白翻转棋,每次翻转一个,必须同时翻转上下左右的一个棋子,求最小的翻转个数。
枚举翻转次数,dfs,找到就输出。 数组设成6*6的,只处理中心的4*4,不需要判断越界也避免了越界问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 #include <iostream> #include <cstring> bool table[6 ][6 ] = {0 };int ans;bool find = 0 ;void output_table () { for (int i = 1 ; i < 5 ; i++) { std::cout << "\n" ; for (int j = 1 ; j < 5 ; j++) { std::cout << table[i][j]; } } } void turn (int a, int b) { table[a][b] = !table[a][b]; table[a-1 ][b] = !table[a-1 ][b]; table[a][b-1 ] = !table[a][b-1 ]; table[a+1 ][b] = !table[a+1 ][b]; table[a][b+1 ] = !table[a][b+1 ]; } bool is_sort () { for (int i = 1 ; i <= 4 ; i++) { for (int j = 1 ; j <= 4 ; j++) { if (table[i][j] != table[1 ][1 ]) { return 0 ; } } } return 1 ; } void dfs (int a, int b, int depth) { if (depth == ans){ find = is_sort (); return ; } if (a == 5 || find) { return ; } turn (a, b); if (b < 4 ) { dfs (a, b+1 , depth + 1 ); } else { dfs (a+1 , 1 , depth + 1 ); } turn (a, b); if (b < 4 ) { dfs (a, b+1 , depth); } else { dfs (a+1 , 1 , depth); } } int main (int argc, char *argv[]) { std::ios::sync_with_stdio (false ); memset (table, 0 , sizeof (table)); char temp[10 ]; for (int i = 0 ; i < 4 ; i++) { std::cin >> temp; for (int j = 0 ; j < 4 ; j++) { if (temp[j] == 'b' ) { table[i+1 ][j+1 ] = 0 ; } else if (temp[j] == 'w' ) { table[i+1 ][j+1 ] = 1 ; } else { continue ; } } } for (ans = 0 ; ans <= 16 ; ans++){ dfs (1 , 1 , 0 ); if (find) { std::cout << ans << std::endl; return 0 ; } } std::cout << "Impossible" << std::endl; return 0 ; }
poj2965 The Pilots Brothers' refrigerator
枚举次数,DFS 和poj1753类似,区别是开关影响不同,本题是那行的横纵列都要改变状态。另一个区别是要记录每次改变的方法。使用结构体或者两个数组存储。 注意再改变状态的时候点(a,b)改变了两次,要再一次改回来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 #include <iostream> #include <cstring> bool table[6 ][6 ] = {0 };int ans;bool find = 0 ;struct solution { int row, col; }N[20 ]; void output_table () { for (int i = 1 ; i < 5 ; i++) { std::cout << "\n" ; for (int j = 1 ; j < 5 ; j++) { std::cout << table[i][j]; } } } void turn (int a, int b) { for (int i = 1 ; i < 5 ; i++) { table[i][b] = !table[i][b]; } for (int i = 1 ; i < 5 ; i++) { table[a][i] = !table[a][i]; } table[a][b] = !table[a][b]; } bool is_open () { for (int i = 1 ; i <= 4 ; i++) { for (int j = 1 ; j <= 4 ; j++) { if (table[i][j] == 1 ) { return 0 ; } } } return 1 ; } void dfs (int a, int b, int depth) { if (depth == ans){ find = is_open (); if (find == 1 ) { std::cout << ans << std::endl; for (int i = 0 ; i < ans; i++) { std::cout << N[i].row << " " << N[i].col << std::endl; } return ; } return ; } if (a == 5 || find) { return ; } turn (a, b); N[depth].row = a; N[depth].col = b; if (b < 4 ) { dfs (a, b+1 , depth + 1 ); } else { dfs (a+1 , 1 , depth + 1 ); } turn (a, b); if (b < 4 ) { dfs (a, b+1 , depth); } else { dfs (a+1 , 1 , depth); } } int main (int argc, char *argv[]) { std::ios::sync_with_stdio (false ); memset (table, 0 , sizeof (table)); char temp[10 ]; for (int i = 0 ; i < 4 ; i++) { std::cin >> temp; for (int j = 0 ; j < 4 ; j++) { if (temp[j] == '-' ) { table[i+1 ][j+1 ] = 0 ; } else if (temp[j] == '+' ) { table[i+1 ][j+1 ] = 1 ; } else { continue ; } } } for (ans = 0 ; ans <= 16 ; ans++){ dfs (1 , 1 , 0 ); } return 0 ; }
POJ 1328 Rader Installation
区间选点问题,贪心解决。 现将区间排序,排序的方法是按区间的右端排序。 每次取区间的右端,如果下一组区间包含取到的区间右端,判断下一组,否则取区间右端。 有一次wa,是因为判断是否为-1的值在循环之后没有置0.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #include <iostream> #include <algorithm> #include <cmath> struct extent { double l, r; }line[1100 ]; bool cmp (extent a, extent b) { return a.r < b.r; } int main (int argc, char *argv[]) { int n, d, cnt_case = 0 , ok; while (std::cin >> n >> d) { ok = 1 ; if (n == 0 && d == 0 ) { break ; } double x, y; for (int i = 0 ; i < n; i++) { std::cin >> x >> y; double temp = double (d * d) - y * y; if (temp < 0 || d < 0 ) { ok = 0 ; } else { line[i].l = x - sqrt (temp); line[i].r = x + sqrt (temp); } } if (!ok) { cnt_case ++; std::cout << "Case " << cnt_case << ": -1" << std::endl; } else { std::sort (line, line + n, cmp); int ans = 1 ; double temp = line[0 ].r; for (int i = 1 ; i < n; i++) { if (temp < line[i].l) { ans++; temp = line[i].r; } } cnt_case ++; std::cout << "Case " << cnt_case << ": " << ans << std::endl; } } return 0 ; }
poj 2109 Power of Cryptography
p的范围...相当可怕,本来以为...要上高精度...然后二分...结果... 看代码吧...
double,一个神奇的类型。 (当然啦这题高精度和二分也能过...但是我这么懒...怎么会写呢... (逃
1 2 3 4 5 6 7 8 9 10 #include <iostream> #include <cmath> int main (int argc, char *argv[]) { double n, p; while (std::cin >> n >> p) { std::cout << pow (p, 1 /n) << std::endl; } return 0 ; }
poj 2586 Y2K Accounting Bug
某个微什么公司,每个月的亏损或者盈利是固定的,每五个月统计一次,所以一年统计了八次,这八次统计...全是亏的...然后要求最高的盈利。
网上说贪心... 其实这才几个月啊...可以自己贪心一下,把那个分段的东西搞出来 换言之,模拟(逃
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <iostream> int main (int argc, char *argv[]) { int s, d, ans; while (std::cin >> s >> d) { if (4 * s < d) { ans = 10 * s - 2 * d; } else if (3 * s < 2 * d) { ans = 8 * s - 4 * d; } else if (2 * s < 3 * d) { ans = 6 * s - 6 * d; } else if (s < 4 * d) { ans = 3 * s - 9 * d; } else { ans = -1 ; } if (ans > 0 ) { std::cout << ans << std::endl; } else { std::cout << "Deficit" << std::endl; } } return 0 ; }
poj 3295 Tautology
哇呜我好牛逼...竟然一次过... 就是一个逻辑版的波兰计算器 压进来弹出去什么的搞一波...具体不说了... 今年第一次用goto! (我还记得小时候学编程所有循环都是goto...后来我脑子就坏掉了 什么都用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 #include <iostream> #include <stack> std::stack<int > expr; int p, q, r, s, t;char expr_input[105 ]; bool solve () { int top = 0 ; int len = strlen (expr_input); for (int i = len - 1 ;i >= 0 ;i--) { switch (expr_input[i]) { case 'p' : expr.push (p); break ; case 'q' : expr.push (q); break ; case 'r' : expr.push (r); break ; case 's' : expr.push (s); break ; case 't' : expr.push (t); break ; case 'K' : { int a = expr.top (); expr.pop (); int b = expr.top (); expr.pop (); expr.push (a&&b); break ; } case 'A' : { int a = expr.top (); expr.pop (); int b = expr.top (); expr.pop (); expr.push (a||b); break ; } case 'N' : { int a = expr.top (); expr.pop (); expr.push (!a); break ; } case 'C' : { int a = expr.top (); expr.pop (); int b = expr.top (); expr.pop (); expr.push ((!a)||b); break ; } case 'E' : { int a = expr.top (); expr.pop (); int b = expr.top (); expr.pop (); expr.push (a==b); break ; } } } return expr.top (); } int main (int argc, char *argv[]) { while (std::cin >> expr_input && expr_input[0 ] != '0' ) { int ok = 1 ; for (p=0 ; p<=1 ; p++) for (q=0 ; q<=1 ; q++) for (r=0 ; r<=1 ; r++) for (s=0 ; s<=1 ; s++) for (t=0 ; t<=1 ; t++) { if (!solve ()) { ok = 0 ; goto out_of_siege; } } out_of_siege: if (ok) { std::cout << "tautology" << std::endl; } else { std::cout << "not" << std::endl; } } return 0 ; }
poj 1860 Currency Exchange
dis数组写成int了 神他妈WA一下午...
bellman_ford求正环,人生第一条图论题...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include <iostream> #define maxn 410 #define inf 0x3f3f3f3f struct edge { int u, v; double rate, com; }side[maxn]; double dis[maxn];int edge_num, node_num, source;double value;void init () { for (int i = 1 ; i <= edge_num; i++) { dis[i] = 0 ; } dis[source] = value; } int bellman_ford () { init (); for (int i = 0 ; i < edge_num; i++) { for (int j = 1 ; j <= 2 * node_num; j++) { if (dis[side[j].v] < (dis[side[j].u] - side[j].com) * side[j].rate){ dis[side[j].v] = (dis[side[j].u] - side[j].com) * side[j].rate; } } } for (int j = 1 ; j <= 2 * node_num; j++) { if (dis[side[j].v] < (dis[side[j].u] - side[j].com) * side[j].rate){ return 1 ; } } return 0 ; } int main (int argc, char *argv[]) { std::cin >> edge_num >> node_num >> source >> value; for (int i = 1 ; i <= 2 * node_num; i += 2 ) { std::cin >> side[i].u >> side[i].v >> side[i].rate >> side[i].com >> side[i+1 ].rate >> side[i+1 ].com; side[i+1 ].u = side[i].v; side[i+1 ].v = side[i].u; } if (bellman_ford ()) { std::cout << "YES\n" ; } else { std::cout << "NO\n" ; } return 0 ; }
POJ1062 昂贵的赠礼 dijkstra
http://poj.org/problem?id=1062 肝爆,现在早上三点了。 最短路,有个条件是等级差...枚举等级区间... 第一条dijkstra...用了大佬的模板... 不说了不说了 睡觉
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 #include <iostream> #include <cstring> #include <vector> #include <queue> #include <algorithm> #include <cmath> #define inf 1000000000 #define maxn 110 int m, n;bool vis[maxn];class dijkstra {private : struct heapnode { int u; int d; heapnode (int u, int d) :u (u), d (d) {} bool operator < (const heapnode &b) const { return d > b.d; } }; struct edge { int v, w; edge (int v, int w) :v (v), w (w) { } }; std::vector<edge> g[maxn]; public : int d[maxn]; int val[maxn]; std::priority_queue<heapnode> q; void clear (int size) { for (int i = 0 ; i <= size; i++) { g[i].clear (); } for (int i = 1 ; i <= size; i++) { d[i] = inf; } memset (vis, 0 , sizeof (vis)); } void addedge (int u, int v, int w) { g[u].push_back (edge (v, w)); } int run (int s) { int u; int min_cost = inf; for (int i = 1 ; i <= n; i++) { d[i] = inf; } d[s] = 0 ; q.push (heapnode (s, 0 )); while (!q.empty ()) { u = q.top ().u; q.pop (); if (!vis[u]) { vis[u] = 1 ; for (std::vector<edge>::iterator e = g[u].begin (); e != g[u].end (); e++) { if (d[e->v] > d[u] + e->w && !vis[e->v]) { d[e->v] = d[u] + e->w; q.push (heapnode (e->v, d[e->v])); } } } } for (int i = 1 ; i <= n; i++) { d[i] += val[i]; min_cost = std::min (min_cost,d[i]); } return min_cost; } }; int main (int argc, char *argv[]) { std::ios::sync_with_stdio (false ); dijkstra bob; int level[maxn]; int ans = inf; std::cin >> m >> n; bob.clear (n); for (int id = 1 ; id <= n; id++) { int substitute; std::cin >> bob.val[id] >> level[id] >> substitute; for (int i = 0 ; i < substitute; i++) { int to, value; std::cin >> to >> value; bob.addedge (id, to, value); } } for (int i = 0 ; i <= m; i++) { for (int j = 1 ; j <= n; j++) { if (level[j] < level[1 ] - m + i || level[j] > level[1 ] + i) { vis[j] = 1 ; } else { vis[j] = 0 ; } } int dij = bob.run (1 ); ans = std::min (ans, dij); } std::cout << ans << std::endl; return 0 ; }