2022.5.6

Codeforces Round #786 (Div. 3)

A - Number Transformation

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        int a,b;
        cin >> a >> b;
        if(a>b||b%a)
        {
            cout << "0 0\n";
        }
        else
        {
            int cnt = b / a;
            cout << "1 "<<cnt<<'\n';
        }
    }

    return 0;
}

B - Dictionary

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        string s;
        cin>>s;
        int tot = s[0] - 'a';
        int cnt = (s[0] - 'a' ) * 26-tot+(s[1]-'a'+1);
        if(s[1]>s[0])
        {
            cnt--;
        }
        cout << cnt << '\n';
    }
    return 0;
}

C - Infinite Replacement

如果替换的串有a的话则可以无限替换(特判只有a一个字母的替换串),如果替换串没有a,则方案数为pow(2,a.length())种。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        string a;
        string b;
        cin >> a >> b;
        if(b.length()==1&&b[0]=='a')
        {
            cout << "1\n";
            continue;
        }
        int f = 0,ff = 0;
        for (int i = 0; i < b.length();i++)
        {
            if(b[i]!='a')
            {
                f = 1;
            }
            else
                ff = 1;
        }
        if(f&&!ff)
        {
            int len = a.length();
            ll ans = pow(2,len);
            cout << ans << '\n';
        }
        else
        {
            cout << "-1\n";
        }
    }

    return 0;
}

D - A-B-C Sort

思路是对的,debug的时候没发现打错字母了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=2e5+10,INF=1e9;
int a[N],b[N];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        int f = 0;
        for (int i = 1; i <= n;i++)
        {
            cin >> a[i];
        }
        memcpy(b, a, sizeof a);
        sort(b + 1, b + 1 + n);
        if(n&1)
        {
            if(a[1]!=b[1])
            {
                cout << "NO\n";
                continue;
            }
        }
        for (int i = n&1?2:1; i <= n; i+=2)
        {
            if((a[i]==b[i]&&a[i+1]==b[i+1])||(a[i]==b[i+1]&&a[i+1]==b[i]))
            {
            }
            else
            {
                f = 1;
                break;
            }
        }
        if(f)
            cout << "NO\n";
        else
            cout << "YES\n";
    }
    return 0;
}

E - Breaking the Wall

每次可以选择一个ai使得a[i]-2且a[i]相邻的数-1,问最少需要多少次操作使得数组至少有2个数<=0?。考虑到最后两个变成0的数,如果它们之间隔的很远,那么操作次数则为(a[i]+1)/2,(a[j]+1)/2,如果它们相邻,则分为两种情况:第一种,如果一个数是另外一个数的两倍以上,那么操作次数为(a[i]+1)/2,第二种,此时的操作次数为ceil(a[i]+a[j]/3.0),如果它们之间相隔1且二者均为奇数,则可以用一次操作让他们都-1,则二者变成偶数,此时花费为(a[i]/2)+(a[j]/2),比二者直接相除花费少1。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=2e5+10,INF=1e9;
ll a[N], b[N];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    for (int i = 1; i <= n;i++)
    {
        cin >> a[i];
        b[i] = a[i];
    }
    ll ans = 0;
    sort(b + 1, b + 1 + n);
    ans = (b[1]+1) / 2 + (b[2]+1) / 2;
    for (int i = 2; i <= n - 1;i++)
    {
        if(a[i-1]%2 && a[i+1]%2)
        {
            ans = min(ans, (a[i - 1] - 1) / 2 + (a[i + 1] - 1) / 2 + 1);
        }
    }
    for (int i = 1; i <= n - 1;i++)
    {
        ll x = a[i], y = a[i+1];
        if(x < y)
            swap(x, y);
        if(x >= y*2)
        {
            ans = min(ans, (x + 1) / 2);
        }
        else
        {
            ans=min(ans,(ll)ceil((x + y)/3.0));
        }
    }
    cout << ans;
    return 0;
}

Codeforces Round #787 (Div. 3)

A - Food for Animals

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        ll a,b,c;
        ll x, y;
        cin >> a >> b >> c >> x >> y;
        int f = 0;
        x -= a, y -= b;
        if(c>=x+y)
            f = 1;
        if(f)cout << "yes\n";
        else
            cout << "no\n";
    }
    
    return 0;
}

B - Make It Increasing

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
ll a[N];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        int f = 0;
        for (int i = 1; i <= n;i++)
            cin >> a[i];

        ll cnt = 0;
        for (int i = n-1; i >= 1;i--)
        {
            if(a[i]>=a[i+1])
            {
                while(a[i]>=a[i+1]&&a[i]!=0)
                {
                    a[i] /= 2;
                    cnt++;
                }
            }
        }
        for (int i = 1; i <n ;i++)
        {
            if(a[i]>=a[i+1])
            {
                f = 1;
                break;
            }
        }
        if(f)
            cout << "-1\n";
        else
            cout << cnt << '\n';
    }

    return 0;
}

C. Detective Task

答案即为最后一个1和第一个0位置相减+1

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        string s;
        cin>>s;
        int n = s.length();
        int pos1 = 0, pos0 = n-1;
        int f = 0;
        for (int i = 0; i < n;i++)
        {
            if(s[i]=='1')
            {
                pos1 = i;
            }
            if(s[i]=='0'&&!f)
            {
                f = 1;
                pos0 = i;
            }
        }
        int res = pos0 - pos1 + 1;
        cout << res << '\n';
    }

    return 0;
}

D - Vertical Paths

从根节点开始dfs,走到叶节点路径加1.

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=2e5+10,INF=1e9;
vector<int> p[N],path[N];
bool vis[N];
int cnt, ans;
void dfs(int x)
{
    if(p[x].size()==0)
    {
        cnt++, ans++;
        return;
    }
    for (int i = 0, j = p[x].size(); i < j; i++)
    {
        if(!vis[p[x][i]])
        {
            vis[p[x][i]] = 1;
            path[cnt].push_back(p[x][i]);
            dfs(p[x][i]);
        }
    }
    return;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        cnt = ans = 0;
        memset(vis,0,sizeof vis);
        int n;
        cin>>n;
        int root = 0;
        for (int i = 1; i <= n;i++)
        {
            int x;
            cin >> x;
            if(x==i)
                root = i;
            else 
                p[x].push_back(i);
        }
        path[0].push_back(root);
        dfs(root);
        cout << ans << '\n';
        for (int i = 0; i < cnt; i++)
        {
            cout << path[i].size() << '\n';
            for (int j = 0; j < path[i].size();j++)
            {
                cout << path[i][j] << ' ';
            }
            cout << '\n';
        }
        cout << '\n';
        for (int i = 0; i <= n;i++)
        {
            p[i].clear();
            path[i].clear();
        }
    }
    return 0;
}

E - Replace With the Previous, Minimize

首先考虑贪心,必定是从前往后改变字典序才能最小,直到不够次数或者遍历完为止,每次改变记录哪些字母是需要改变的,最后输出的时候将字母改变即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
bool vis[30];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        memset(vis, 0, sizeof vis);
        int n, k;
        cin>>n>>k;
        string s;
        cin >> s;
        for (int i = 0, cnt = 0; i < n && cnt < k;i++)
        {
            while((s[i]!='a')&&!vis[s[i]-'a']&&cnt<k)
            {
                vis[s[i] - 'a'] = 1;
                s[i]--;
                cnt++;
            }
        }
        for (int i = 0; i < n;i++)
        {
            while(vis[s[i]-'a'])
                s[i]--;
            cout << s[i];
        }
        cout << '\n';
    }
    return 0;
}
posted @ 2022-05-06 21:37  menitrust  阅读(22)  评论(0编辑  收藏  举报