Codeforces Beta Round #3 A、B、C、D解题报告……
苗条
posted @ 2010年3月09日 00:32
in codeforces
, 2553 阅读
A题 bfs 注意下方向基本不会错的……
代码头文件在首贴(估计咱这个地方也没人会来)……
const int dir[8][2] = {-1, 0, 1, 0, 0, -1, 0, 1, -1, -1, -1, 1, 1, 1, 1, -1}; const string dirs[8] = {"L\n","R\n","D\n","U\n","LD\n","LU\n","RU\n","RD\n"}; int map[10][10], sx, sy, ex, ey; string s, e; bool mark[10][10]; class node { public: int x; int y; string res; int step; }; void init() { sx = s[0] - 'a'; sy = s[1] - '1'; ex = e[0] - 'a'; ey = e[1] - '1'; CC (mark, false); } void hexie() { init(); queue<node> Q; node p, q; int i, j, k; p.x = sx; p.y = sy; p.step = 0; p.res = ""; mark[sx][sy] = true; Q.push(p); while ( !Q.empty() ) { p = Q.front(); if ( p.x == ex && p.y == ey ) { cout << p.step << endl; cout << p.res; return; } Q.pop(); FF (i, 8) { q = p; q.x += dir[i][0]; q.y += dir[i][1]; if ( q.x < 0 || q.y < 0 || q.x > 7 || q.y > 7 || mark[q.x][q.y] ) continue; mark[q.x][q.y] = true; ++q.step; q.res += dirs[i]; Q.push(q); } } } int main() { while ( cin >> s >> e ) { hexie(); } return 0; }
B题 贪心,这题可以看成一个物品体积为1,2的特殊背包问题,表示可以用贪心解决,
先分1,2两类排序,然后开始贪心,具体策略由于文字表达能力太差,可以直接参考代码……
class node { public: int idx; int lv; int value; }; node t1[100010]; node t2[100010]; int li[100010]; int m, n; bool cmp(node &a, node &b) { return a.value > b.value; } void hexie() { int i, j, k, num1, num2, lv, value, rear; int res = 0; rear = num1 = num2 = 0; FOR (i, 1, n+1 ) { scanf("%d%d", &lv, &value); if ( lv == 1 ) { t1[num1].lv = lv; t1[num1].value = value; t1[num1].idx = i; ++num1; } else { t2[num2].lv = lv; t2[num2].value = value; t2[num2].idx = i; ++num2; } } sort(t1, t1+num1, cmp); sort(t2, t2+num2, cmp); i = j = 0; while ( m > 0 ) { if ( i < num1 && j < num2 ) { if ( i+1 < num1 && t1[i].value + t1[i+1].value > t2[j].value ) { --m; res += t1[i].value; li[rear++] = t1[i].idx; ++i; } else if ( i < num1 && ( t1[i].value > t2[j].value || m == 1 ) ) { --m; res += t1[i].value; li[rear++] = t1[i].idx; ++i; } else if ( m >= 2 ) { m -= 2; res += t2[j].value; li[rear++] = t2[j].idx; ++j; } else { --m; res += t1[i].value; li[rear++] = t1[i].idx; ++i; } } else if ( i < num1 ) { --m; res += t1[i].value; li[rear++] = t1[i].idx; ++i; } else if ( m >= 2 && j < num2 ) { m -= 2; res += t2[j].value; li[rear++] = t2[j].idx; ++j; } else { break; } } printf("%d\n", res); FF(i, rear) printf( i == rear-1 ? "%d\n" : "%d ", li[i]); } int main() { while ( ~scanf("%d%d", &n, &m) ) { hexie(); } return 0; }
C题 直接模拟,表示题意看的头晕,在领导的指导下,完成ac……
char a[3][3]; int main() { int numx, numo, i, j, k; bool x, o; while ( gets(a[0]) ) { gets(a[1]); gets(a[2]); numx = numo = 0; x = o = false; FF (i, 3) { if ( a[i][1] == a[i][2] && a[i][2] == a[i][0] ) { if ( a[i][0] == 'X' ) x = true; else if ( a[i][0] == '0' ) o = true; } if ( a[1][i] == a[2][i] && a[2][i] == a[0][i] ) { if ( a[0][i] == 'X' ) x = true; else if ( a[0][i] == '0' ) o = true; } FF (j, 3) { if ( a[i][j] == 'X' ) ++numx; else if ( a[i][j] == '0' ) ++numo; } } if ( a[0][0] == a[1][1] && a[1][1] == a[2][2] ) { if ( a[0][0] == 'X' ) x = true; else if ( a[0][0] == '0' ) o = true; } if ( a[0][2] == a[1][1] && a[1][1] == a[2][0] ) { if ( a[2][0] == 'X' ) x = true; else if ( a[2][0] == '0' ) o = true; } if ( abs(numx-numo) > 1 || (o&&x) || (numo==numx && x) || (numo==numx-1 && o) || numx-numo < 0) { puts("illegal"); } else if ( numo == numx && numo == 0 ) { puts("draw"); } else if ( numo + numx == 9 ) { if ( x ) puts("the first player won"); else if ( o ) puts("the second player won"); else puts("draw"); } else if ( x ) { puts("the first player won"); } else if ( o ) { puts("the second player won"); } else if ( numo == numx ) { puts("first"); } else { puts("second"); } } return 0; }
D题非常巧妙的贪心,贪心策略是假设每个'?' 都为 ')' ,并记录修改成 '(' 的代价,用优先队列保存,
遍历时候如果出现')' 无法被匹配的情况, 则作一次出队操作一个即可, 若队列空, 直接-1之。
更详细解说及代码推荐 白衣少年 的报告中的写法。
2010年11月12日 20:11
问下A题为什么宽度优先搜索到的一定是最短距离?
2010年11月12日 20:53
哦,我明白了,很明显嘛,我2了,呵呵