Educational Codeforces Round 58 (Rated for Div. 2)

http://codeforces.com/contest/1101

A题

判断d在不在 l,r区间内  如果不在就直接输出d  如果在  就用 (r/d+1)*d  求得在超过r后第一个是d的整数倍的数字

#include
using namespace std;
typedef long long ll;
const int N = 1e6+100;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;

int main()
{
    ll l,r,d;
    int q;
    cin >> q;
    while(q --){
        cin >> l >> r >> d;
        if(d < l || d > r)
            cout << d << '\n';
        else
            cout << (r/d+1)*d << '\n';
    }
    return 0;
}

B题

根据题中的规则,可知 手风琴的 样式为 [ : ||...|| :] 中间的|个数可以不限,但是必须是这个样式,所有暴力找边界,然后统计中间有多少个|即可

#include
using namespace std;
typedef long long ll;
const int N = 1e6+100;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;

int main()
{
    string s;
    cin >> s;
    int l1,l2,r1,r2;
    l1 = l2 = r1 = r2 = -1;
    int cnt = 0;
    int i;
    for(i = 0;i < s.size();i ++){
        if(s[i] == '['){
            l1 = i;
            break;
        }
    }
    for(;i < s.size();i ++){
        if(s[i] == ':'){
            l2 = i;
            break;
        }
    }
    int j;
    for(j = s.size()-1;j >= 0;j --){
        if(s[j] == ']'){
            r1 = j;
            break;
        }
    }
    for(;j >= 0;j --){
        if(s[j] == ':'){
            r2 = j;
            break;
        }
    }
    //cout << l1 << r1 << l2 << r2;
    if(l1 == -1 || l2 == -1 || r1 == -1 || r2 == -1)
        cout << -1;
    else if(l1 < r1 && l2 < r2 && l1 < l2 && r1 > r2){
        for(i = l2 + 1;i < r2;i ++){
            if(s[i] == '|')
                cnt ++;
        }
        cout << 4 + cnt;
    }else{
        cout << -1;
    }
    return 0;
}

C题

这题离线处理一下,记录id  然后按照 L  升序排序  从第二个开始遍历,如果此时的 L 大于目前所遍历过的区间的最大R,则说明从这个区间开始就断开了,即没用交点了,所以断点以前可以分为一组,断点以后可以分为一组

#include
using namespace std;
typedef long long ll;
const int N = 2e5+100;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
struct seg{
    int l,r,id;
    friend bool operator < (const seg &a,const seg &b){
        return a.l < b.l;
    }
}s[N];
int ans[N];
int main()
{
    int T;
    scanf("%d",&T);
    while(T --){
        memset(ans,0,sizeof(ans));
        int n;
        scanf("%d",&n);
        for(int i = 1;i <= n;i ++){
            scanf("%d%d",&s[i].l,&s[i].r);
            s[i].id = i;
        }
        sort(s + 1,s + n + 1);
        int p = 0;
        int _maxr = s[1].r;
        for(int i = 2;i <= n;i ++){
            if(s[i].l > _maxr){
                p = i;
                break;
            }
            _maxr = max(_maxr,s[i].r);
        }
        if(p == 0) cout << -1;
        else{
            for(int i = 1;i <= n;i ++) ans[s[i].id] = i

E题

根据题中要求,每次询问x y 都要小于对应的 h w或 w h  那么如果是+ 则记录下此时的最大左边界和最大右边界

如果是?则直接和我们记录的最大左右边界比较即可,如果此时满足,证明所有账单都满足

#include
using namespace std;
typedef long long ll;
const int N = 1e6+100;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
int main()
{
    int n;
    cin >> n;
    char op[2];
    int x,y,h,w;
    int l,r;
    l = 0;
    r = 0;
    while(n --){
        scanf("%s",op);
        if(op[0] == '+'){
            scanf("%d%d",&x,&y);
            l = max(l,min(x,y));
            r = max(r,max(x,y));
        }else{
            scanf("%d%d",&h,&w);
            if(l <= min(h,w) && r <= max(h,w))
                cout << "YES" << '\n';
            else
                cout << "NO" << '\n';
        }
    }
    return 0;
}

 

你可能感兴趣的:(Codeforces)