codeforces竞赛1169题解

A. Circle Metro

题目大意:

两个人乘坐不同方向的环形地铁,求两人是否会在某一站点相遇。

解题思路:

模拟即可

AC代码:

  • 版本一(下标模拟)
#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    while(cin >> n){
        int a, x, b, y;
        cin >> a >> x >> b >> y;
        int i = a, j = b;
        bool flag = false;
        while(true){
            if(i == j){
                flag = true;
                break;
            }
            if(i == x)break;
            if(j == y)break;
            i++;
            if(i > n)i = 1;
            j--;
            if(j < 1)j = n;
        }
        if(flag){
            cout << "YES" << endl;
        }else{
            cout << "NO" << endl;
        }
    }
    return 0;
}
  • 版本二(队列模拟)
#include<bits/stdc++.h>

using namespace std;
typedef unsigned long long LL;

template<typename T>
inline void oo(string str, T val) { cerr << str << val << endl; }

template<typename T>
inline T read() {
    T x;
    cin >> x;
    return x;
}

#define FOR(i, x, y) for (decay<decltype(y)>::type i = (x), _##i = (y); i < _##i; ++i)
#define FORD(i, x, y) for (decay<decltype(x)>::type i = (x), _##i = (y); i > _##i; --i)

int main() {
    int n(read<int>());
    int a(read<int>()), x(read<int>()), b(read<int>()), y(read<int>());
    queue<int> P, Q;
    for (int i = 1; i <= n * n; i++)Q.push(i % n + 1);
    for (int i = n * n; i >= 1; i--)P.push(i % n + 1);

    while (Q.front() != a)Q.pop();
    while (P.front() != b)P.pop();
    bool flag = false;
    while (Q.front() != x and P.front() != y) {
        Q.pop();
        P.pop();
        if (Q.front() == P.front()) {
            flag = true;
            break;
        }
    }
    cout << (flag ? "YES" : "NO") << endl;
    return 0;
}

B. Pairs

题目大意:

给出n个点,m条边,每条边有两个定点。是否可以找出两个点x,y,使得所有的边要么与x相连,要么与y相连。

解题思路:

将点边集合看成图,找出图中两个度数最大的点,删掉这两个点及其相关的边后,检测图中是否就没有边了。操作步骤如下:

  1. 将所有的边以pair点对的形式放到set集合里面去(可以去重).
  2. 然后统计每个点的度数,用map存放每个点和它的度数值。
  3. 然后找出最大的度数的点,将这个点的所有连边从set中移除,并且与这个点相邻的点的度数减一。
  4. 重新找度数最大的点,重复步骤2,3
  5. 判断存放边的集合set是否为空,如果为空,则输出YES,否则输出NO。

备注:

set的迭代器删除的时候,要写成 S.erase(edge++),而不能写成 S.erase(edge);edge++;因为执行完删除操作后,迭代器已失效,此处是个坑,得留心

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main() {
   // ifstream cin("input.txt");
    int n, m;
    cin >> n >> m;
    set<pair<int, int> >S;
    for(int i = 1; i <= m; i++) {
        int a, b;
        cin >> a >> b;
        S.insert({a, b});
    }
    map<int, int>M;
    for(auto i : S) {
        M[i.first]++;
        M[i.second]++;
    }
    for(int i = 0; i < 2; i++) {
        if(S.size() == 0)break;
        int u = 1, MAX = 0;
        for(auto i : M){
            if(i.second > MAX){
                u = i.first;
                MAX = i.second;
            }
        }
        for(auto edge = S.begin(); edge != S.end();) {
            if(edge->first == u || edge->second == u) {
                M[edge->first]--;
                M[edge->second]--;
                S.erase(edge++);
            }else{
                edge++;
            }
        }
    }
    if(S.size() == 0) {
        cout << "YES" << endl;
    } else {
        cout << "NO" << endl;
    }
    return 0;
}
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值