Codeforces Round #805 (Div. 3)

练一套div3

A - Round Down the Price

#include<iostream>
#include<bits/stdc++.h>

using namespace std;
#define four(i, a, b) for(int i=a;i<=b;i++)
#define fourr(i, a, b) for(int i=a;i>=b;i--)
#define Max(a, b) (a>b?a:b)
#define Min(a, b) (a<b?a:b)
#define ll long long
#define inf 0x3f3f3f3f
#define mem(a, b) memset(a,b,sizeof(a))
#define lowbit(x) (x&(-x))
const ll maxn = 1e3 + 5;
const ll maxm = 1e5 + 5;
const ll mod = 233333;
int t;
int fun(int m){
    int b=1;
    while(m>b){
        b*=10;
    }
    if (m<b)b/=10;
    return b;
}
void sol(){
    int m;
    scanf("%d",&m);
cout<<m- fun(m)<<endl;
}
int main() {
scanf("%d",&t);
while(t--){
    sol();
}
}

B - Polycarp Writes a String from Memory

#include<iostream>
#include<bits/stdc++.h>

using namespace std;
#define four(i, a, b) for(int i=a;i<=b;i++)
#define fourr(i, a, b) for(int i=a;i>=b;i--)
#define Max(a, b) (a>b?a:b)
#define Min(a, b) (a<b?a:b)
#define ll long long
#define inf 0x3f3f3f3f
#define mem(a, b) memset(a,b,sizeof(a))
#define lowbit(x) (x&(-x))
const ll maxn = 2e5 + 5;
const ll maxm = 1e5 + 5;
const ll mod = 233333;
int t;
char s[maxn];
bool vis[30];

void sol() {
    mem(vis,0);
    scanf("%s", s);
    int len = strlen(s);
    int ans = 1;
    int lim=0;
    for (int i = 0; s[i];) {
        while (vis[s[i]-'a'])
            i++;
        if (!s[i])break;
        if (lim >= 3) {
            ans++;
            lim = 0;
            mem(vis,0);
        }else{
            lim++;
            vis[s[i++]-'a']=1;
        }
    }
    cout<<ans<<endl;
}

int main() {
    scanf("%d", &t);
    while (t--) {
        sol();
    }


}

C - Train and Queries
两个map记录一下每个数字出现的最早位置和最晚位置,然后比较即可

#include<iostream>
#include<bits/stdc++.h>

using namespace std;
#define four(i, a, b) for(int i=a;i<=b;i++)
#define fourr(i, a, b) for(int i=a;i>=b;i--)
#define Max(a, b) (a>b?a:b)
#define Min(a, b) (a<b?a:b)
#define ll long long
#define inf 0x3f3f3f3f
#define mem(a, b) memset(a,b,sizeof(a))
#define lowbit(x) (x&(-x))
const ll maxn = 2e5 + 5;
const ll maxm = 1e5 + 5;
const ll mod = 233333;
int t;
int a[maxn];
map<int, int> pos[2];

void sol() {
    int n, m;
    scanf("%d%d", &n, &m);
    pos[1].clear();
    pos[0].clear();
    four(i, 1, n) {
        scanf("%d", &a[i]);
        if (!pos[0][a[i]]) {
            pos[1][a[i]] = pos[0][a[i]] = i;
        } else {
            pos[1][a[i]] = Max(pos[1][a[i]], i);
        }
    }
    four(i, 1, m) {
        int a, b;
        scanf("%d%d", &a, &b);
        if (!pos[0][a] || !pos[1][b])
            puts("NO");
        else if (pos[0][a] < pos[1][b])
            puts("YES");
        else
            puts("NO");
    }


}

int main() {
    scanf("%d", &t);
    while (t--) {
        sol();
    }


}

D - Not a Cheap String
开个结构体,存放下标、数据、是否删除的状态。
先根据数据排序,删最大的,这样步数一定最小,删的时候标记位改一下。
然后根据:先标记位后下标的优先级再排序就ok了

#include<iostream>
#include<bits/stdc++.h>

using namespace std;
#define four(i, a, b) for(int i=a;i<=b;i++)
#define fourr(i, a, b) for(int i=a;i>=b;i--)
#define Max(a, b) (a>b?a:b)
#define Min(a, b) (a<b?a:b)
#define ll long long
#define inf 0x3f3f3f3f
#define mem(a, b) memset(a,b,sizeof(a))
#define lowbit(x) (x&(-x))
const ll maxn = 2e5 + 5;
const ll maxm = 1e5 + 5;
const ll mod = 233333;
int t;
char s[maxn];
struct node{
    char dt;
    int id;
    bool sta;
}st[maxn];
bool cmp(node a, node b){
    return a.dt>b.dt;
}
bool cmp1(node a,node b){
    if(a.sta==b.sta)return a.id<b.id;
    return a.sta<b.sta;
}
void sol() {
    scanf("%s",s);
    int m;
    scanf("%d",&m);
    int len= strlen(s);
    int sum=0;
    for(int i=0;s[i];i++){
        st[i].dt=s[i];
        sum+=s[i]-'a'+1;
        st[i].id=i;
        st[i].sta=0;
    }
    sort(st,st+len,cmp);
    int i=0;
    while(sum>m&&i<len){
        sum-=st[i].dt-'a'+1;
        st[i].sta=1;
        i++;
    }
    sort(st,st+len,cmp1);
    for(i=0;!st[i].sta&&i<len;i++){
        putchar(st[i].dt);
    }
    puts("");
}

int main() {
    scanf("%d", &t);
    while (t--) {
        sol();
    }


}

E - Split Into Two Sets
这题不会,好像是二分图,留坑

F - Equate Multisets
首先搞明白一个关键:b/2是为了分解非2质因子。
而b*2可以转换为a/2(a是偶数的情况)。
此时a/2的目的是去掉所有的因子2。
这样一来使a==b,就变成提取关键非2质因子了。
我们先把a、b全除成奇数,再一步一步拆b看看能不能拆出关键因子。
比如a30 b21,可以转换为a5 b21->10->5就得到关键因子5了。
关键质因子就是从其他非2质因子里拆出来的,所以一步步试就行了。
越大的关键质因子越要先凑,所以ab大顶堆。当b最大的元素比关键因子小了,说明凑不出来了,直接no。

#include<iostream>
#include<bits/stdc++.h>

using namespace std;
#define four(i, a, b) for(int i=a;i<=b;i++)
#define fourr(i, a, b) for(int i=a;i>=b;i--)
#define Max(a, b) (a>b?a:b)
#define Min(a, b) (a<b?a:b)
#define ll long long
#define inf 0x3f3f3f3f
#define mem(a, b) memset(a,b,sizeof(a))
#define lowbit(x) (x&(-x))
const ll maxn = 2e5 + 5;
const ll maxm = 1e5 + 5;
const ll mod = 233333;
int t;
int n;

//int a[maxn];
//int b[maxn];
void sol() {
    scanf("%d", &n);
    priority_queue<int> a, b;
    int k;
    four(i, 1, n) {
        scanf("%d", &k);
        while (k % 2 == 0) {
            k /= 2;
        }
        a.push(k);
    }
    four(i, 1, n) {
        scanf("%d", &k);
        while (k % 2 == 0) {
            k /= 2;
        }
        b.push(k);
    }
    while (!b.empty()) {
        k = b.top();
        b.pop();
        if (k == a.top()) {
            a.pop();
        } else if (k < a.top()) {
            puts("NO");
            return;
        } else {
            k /= 2;
            if (k % 2 == 0)k /= 2;
            b.push(k);
        }
    }
    puts("YES");
}

int main() {
    cin >> t;
    while (t--)
        sol();


}

G2 Passable Paths (hard version)
挺难想的一道题(对我来说)看了别人的题解才有启发
确认序列都在一条链上就ok,换句话说就是走过的每个点分支不超过2。那么给这条链找端点p1,p2。
令p1是深度最大的点好理解。
令p2为p1异分支上的点,这样一旦有个点不在p1或p2的分支上就no了,同样让p2深度尽可能大,lca(p1,p2)!=p2就是异分支,如果找不到这个点,说明每个点都与p1同支,直接yes。
处理完p1p2之后,对每个p分别求lca(p1,p)=a1,lca(p2,p)=a2,lca(p1,p2)=a;在p合法的情况下,有:

  1. 若p与p1同支,那么a1应等于p,a2应等于a
  2. 若p与p2同支,那么a1应等于a,a2应等于p
    符合其中一个就ok,不符合false
#include<iostream>
#include<bits/stdc++.h>

using namespace std;
//#pragma GCC optimize(3)

#define endl "\n"
#define four(i, a, b) for(int i=a;i<=b;i++)
#define fourr(i, a, b) for(int i=a;i>=b;i--)
#define Max(a, b) (a>b?a:b)
#define Min(a, b) (a<b?a:b)
#define ll long long
#define inf 0x3f3f3f3f
#define mem(a, b) memset(a,b,sizeof(a))
#define lowbit(x) (x&(-x))
const ll maxn = 2e5 + 5;
const ll maxm = 1e5 + 5;
const ll mod = 233333;
int d[maxn];
int f[maxn][20];
int n;
vector<int> v[maxn];
int queries[maxn];

int lca(int a, int b) {
    if (d[a] != d[b]) {
        if (d[a] < d[b])
            swap(a, b);
        int dis = d[a] - d[b];
        for (int i = 0; (1 << i) <= n; ++i) {
            if ((1 << i) & dis) {
                a = f[a][i];
            }
        }
    }
    if (a == b)return a;
    for (int i = 19; i >= 0; i--) {
        if (f[a][i] != 0 && f[b][i] != 0 && f[a][i] != f[b][i]) {
            a = f[a][i];
            b = f[b][i];
        }
    }
    return f[a][0];
}

void bfs() {
    d[1] = 1;
    queue<int> q;
    q.push(1);
    while (!q.empty()) {
        int t = q.front();
        q.pop();
        for (const auto &item: v[t]) {
            if (d[item]) continue;
            d[item] = d[t] + 1;
            f[item][0] = t;
            for (int i = 1; i < 20; ++i) {
                f[item][i] = f[f[item][i - 1]][i - 1];
            }
            q.push(item);
        }
    }
}

int main() {
//    ios::sync_with_stdio(false);
//    cin.tie(0);
//    cout.tie(0);
    cin >> n;
    four(i, 1, n - 1) {
        int a, b;
        cin >> a >> b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
    bfs();
    int q;
    cin >> q;
    while (q--) {
        int k;
        cin >> k;
        bool ok = 1;
        int p1 = -1, p2 = -1;
        four(i, 1, k) {
            cin >> queries[i];
            if (p1 == -1 || d[p1] < d[queries[i]])p1 = queries[i];
        }
        four(i, 1, k) {
            if (queries[i] == p1)continue;
            int t_lca = lca(p1, queries[i]);
            if (t_lca != queries[i]) {
                if (p2 == -1 || d[p2] < d[queries[i]])
                    p2 = queries[i];
            }
        }
        if (p2 == -1)cout << "YES\n";
        else {
            four(i, 1, k) {
                if (queries[i] == p1 || queries[i] == p2)
                    continue;
                int a1 = lca(p1, queries[i]);
                int a2 = lca(p2, queries[i]);
                int a = lca(p1, p2);
                if(!((a1==a&&a2==queries[i])||(a2==a&&a1==queries[i]))){
                    ok=0;
                    break;
                }
            }
            puts((ok?"YES":"NO"));
        }

    }
}

总结:不会的东西太多,慢慢补。需要提高一下做题速度,简单的模拟上少花点时间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值