codeforce round #217

来源:互联网 发布:大数据是如何产生的 编辑:程序博客网 时间:2024/05/29 15:20

A题:

rook的话如果同行同列就一次,否则两次。

bishop,首先如果一个在白色位置,另外一个在黑色位置是不可达的。

否则再一条对角线上就一次,其余位置两次。

king,bfs()一次求出答案。

AC代码:

#include <cstdio>#include <cstring>const int MAX_NUMBER = 1007;struct Point {    int x, y, steps;};int n;int start_x, start_y, end_x, end_y;int ans_1, ans_2, ans_3;int step[8][2] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}};int vis[10][10];struct Point point[MAX_NUMBER];void bfs() {    memset(vis, 0, sizeof(vis));    point[0].x = start_x;    point[0].y = start_y;    vis[start_x][start_y] = 1;    int front = 0;    int rear = 1;    while (front < rear) {        struct Point cnt_point = point[front];        int cnt_x = cnt_point.x;        int cnt_y = cnt_point.y;        if (cnt_x == end_x && cnt_y == end_y) {            ans_3 = cnt_point.steps;            return ;        }        for (int i = 0; i < 8; i++) {            int next_x = cnt_x + step[i][0];            int next_y = cnt_y + step[i][1];            if (next_x >= 1 && next_x <= 8 && next_y >= 1 && next_y <= 8 && !vis[next_x][next_y]) {                vis[next_x][next_y] = 1;                point[rear].x = next_x;                point[rear].y = next_y;                point[rear].steps = cnt_point.steps + 1;                rear++;            }        }        front++;    }}int main() {    scanf("%d%d%d%d", &start_x, &start_y, &end_x, &end_y);    if (start_x == end_x || start_y == end_y) {        ans_1 = 1;    }    else {        ans_1 = 2;    }    if ((start_x + start_y) % 2 != (end_x + end_y) % 2) {        ans_2 = 0;    }    else if (start_x + start_y == end_x + end_y || start_x - start_y == end_x - end_y) {        ans_2 = 1;    }    else {        ans_2 = 2;    }    bfs();    printf("%d %d %d\n", ans_1, ans_2, ans_3);    return 0;}


B题:

O(n ^ 2),枚举判断一个集合是不是另一个集合的子集或者真子集。

如果是真子集的话,那么超集就不可能赢。如果是想等的话两个都不可能赢,其他情况可能赢。

AC代码:

#include <cstdio>#include <cstring>#include <vector>#include <algorithm>#include <set>using namespace std;const int MAX_NUMBER = 107;vector<int> player[MAX_NUMBER];set<int> player_set[MAX_NUMBER];int vis[MAX_NUMBER], ans[MAX_NUMBER];int player_number;int main() {    memset(vis, 0, sizeof(vis));    scanf("%d", &player_number);    for (int i = 1; i <= player_number; i++) {        int cnt_number;        scanf("%d", &cnt_number);        for (int j = 1; j <= cnt_number; j++) {            int temp;            scanf("%d", &temp);                        player_set[i].insert(temp);            player[i].push_back(temp);        }    }    int n = 1;    memset(ans, -1, sizeof(ans));    for (int i = 1; i <= player_number; i++) {        for (int j = i + 1; j <= player_number; j++) {            int flag = 0;            if (player[i].size() == player[j].size()) {                for (int k = 0; k < player[j].size(); k++) {                    if (!player_set[i].count(player[j][k])) {                        flag = 1;                        break;                    }                }                if (!flag) {                    ans[i] = ans[j] = 0;                }            }            else if (player[i].size() < player[j].size()) {                for (int k = 0; k < player[i].size(); k++) {                    if (!player_set[j].count(player[i][k])) {                        flag = 1;                        break;                    }                }                if (!flag) {                    ans[j] = 0;                }            }            else {                for (int k = 0; k < player[j].size(); k++) {                    if (!player_set[i].count(player[j][k])) {                        flag = 1;                        break;                    }                }                if (!flag) {                    ans[i] = 0;                }            }        }    }    for (int i = 1; i <= player_number; i++) {        if (ans[i] == -1) {            printf("YES\n");        }        else {            printf("NO\n");        }    }    return 0;}


C题:

贪心。

每次对各种颜色有的手套数进行排序,颜色最少的和颜色最多的去匹配。

匹配到最后无法匹配的只能和自己匹配了。

但是这种贪心不是正确的,比如说颜色1:7个人,颜色2:5个人,颜色3:1个人,颜色4:3个人。

按这种贪心的话,

先匹配3- 1,1-3,然后4-1,1-4,4-1,1-4,接下来再1-2,2-1,1-2,2-1,1-2,2-1

最后颜色2还剩下4只手套,只能是2-2,2-2,但是有一种明显更好的方式,比如说最后的2和3-1的随便一个进行交换,答案会多出来。

所有我的做法是先贪心,贪心完后看是否能不能和前面的手套进行交换使结果更好,如果能的话肯定要交换,得出最后的答案。

AC代码:

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAX_NUMBER = 100007;struct Color {    int color, number;};struct Ans {    int x, y;};struct Ans ans[MAX_NUMBER];bool cmp(struct Color a, struct Color b) {    return a.number < b.number;}struct Color color[MAX_NUMBER];int vis[MAX_NUMBER];int color_number, ans_number, children, pre_number, diff;void deal() {    pre_number = color_number;    sort(color + 1, color + color_number + 1, cmp);    color_number = 0;    for (int i = 1; i <= pre_number; i++) {        if (color[i].number != 0) {            color[++color_number].color = color[i].color;            color[color_number].number = color[i].number;        }    }    if (color_number >= 2) {        for (int i = 0; i < color[1].number; i += 2) {            ans[ans_number].y = color[1].color;            ans[ans_number].x = color[color_number].color;            ans_number++;            ans[ans_number].x = color[1].color;            ans[ans_number].y = color[color_number].color;            ans_number++;        }        color[color_number].number -= color[1].number;             color[1].number = 0;        diff = ans_number;    }    else if (color_number == 1){        for (int i = 0; i < color[1].number; i += 2) {            ans[ans_number].x = color[1].color;            ans[ans_number].y = color[1].color;            ans_number++;        }        color_number = 0;    }}int main() {    int m;    scanf("%d%d", &children, &m);    memset(color, 0, sizeof(color));    memset(vis, 0, sizeof(vis));    color_number = 0;    for (int i = 1; i <= m; i++) {        color[i].color = i;    }    for (int i = 1; i <= children; i++) {        int temp;        scanf("%d", &temp);        if (!vis[temp]) {            vis[temp] = 1;            color[temp].number = 2;        }        else {            color[temp].number += 2;        }    }    color_number = m;    while (1) {        deal();        if (color_number == 0) {            break;        }    }    int final_result = diff;        if (ans_number != diff) {        int cnt_number = 0;        for (int i = 0; i < diff && cnt_number < ans_number - diff; i++) {            if (ans[i].x != ans[diff + cnt_number].x && ans[i].y != ans[diff + cnt_number].y) {                int temp = ans[diff + cnt_number].x;                ans[diff + cnt_number].x = ans[i].x;                ans[i].x = temp;                final_result++;                cnt_number++;            }        }    }    printf("%d\n", final_result);    for (int i = 0; i < ans_number; i++) {        printf("%d %d\n", ans[i].x, ans[i].y);    }    return 0;}
D题:

没看懂题目意思= =