Educational Codeforces Round 78 (Rated for Div. 2)

题库链接

https://codeforces.com/contest/1278

A. Shuffle Hashing

给定两个字符串p,h,问 h能不能由s1+p'+s2组成 ,p'是p的重新排列,长度<100
暴力

#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 110;
const int M = 1e9+7;
int n,m,k,t;
 
char s[maxn],h[maxn];
int a[30],b[30];
 
bool judge()
{
    for(int i = 0; i < 30; i++)
    {
        if(a[i] != b[i]) return false;
    }
    return true;
}
 
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("data.in", "r", stdin);
    //freopen("data.out", "w", stdout);
#endif
    cin(t);
    while (t--)
    {
        cin>>s>>h;
        mem(a,0);
        int lens = strlen(s);
        int lenh = strlen(h);
        for(int i = 0; i < lens; i++)
        {
            a[s[i]-'a']++;
        }
        bool flag = false;
        for(int i = 0; i+lens <= lenh; i++)
        {
            if(a[h[i]-'a'])
            {   
                //cout<<i<<' ';
                mem(b,0);
                for(int j = 0; j < lens; j++)
                {
                    b[h[i+j]-'a']++;
                }
                if(judge())
                {
                    flag = true;
                    break;
                }
            }
        }
        if(flag) puts("YES");
        else puts("NO");
    }
    return 0;
}

B. A and B

给定a,b ,第i次可以把i加到a或者b,求让a,b相等的最小操作数

#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 100100;
const int M = 1e9+7;
int n,a,b,t;
 
ll arr[maxn];
 
int search(int k)
{
    for(int i = 0; i < maxn-2; i++)
    {   
        if(arr[i] < k) continue;
        if(arr[i] == k) return i;
        if((arr[i]-k)%2 == 0) return i;
    }
}
 
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("data.in", "r", stdin);
    //freopen("data.out", "w", stdout);
#endif
    for(int i = 1; i < maxn; i++)
    {
        arr[i] = arr[i-1]+i;
    }
    cin(t);
    while (t--)
    {
        cin>>a>>b;
        n = abs(a-b);
        n = search(n);
        cout<<n<<endl;
    }
    return 0;
}

C. Berry Jam

有2*n罐果酱,有蓝莓酱和草莓酱,主角在n和(n+1)之间,问最少吃多少(只能吃附近的),使得剩下的蓝莓酱等于草莓酱
我这题因为漏了一个条件写自闭了,方法就是统计出左边吃i个会得到的差值,和右边吃i个会得到的差值,然后去枚举,使得左+右等于蓝莓和草莓的差值

#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 100100;
const int M = 1e9+7;
int n,m,k,t;
 
int a[maxn];
 
int ans1[maxn];
int ans2[maxn];
 
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("data.in", "r", stdin);
    //freopen("data.out", "w", stdout);
#endif
    cin(t);
    while (t--)
    {
        cin(n);
        int x = 0, y = 0;
        ans1[0] = ans2[0] = 0;
        for(int i = n; i >= 1; i--)
        {
            cin(a[i]);
            if(a[i] == 1) x++;
            else y++;
        }
        for(int i = 1,c; i <= n; i++)
        {
            cin(c);
            if(c == 1) x++,ans2[i] = ans2[i-1]+1;
            else y++,ans2[i] = ans2[i-1]-1;
        }
        for(int i = 1; i <= n; i++)
        {
            if(a[i] == 1) ans1[i] = ans1[i-1]+1;
            else ans1[i] = ans1[i-1]-1;
        }
 
        int ans = inf;
        int temp = x-y;
 
        for(int k = abs(x-y); k <= 2*n && ans == inf; k+=2)
        {
            for(int i = 0; i <= k; i++)
            {   
                if(i <= n && k-i <= n)            //wa到自闭,没有考虑到数组可能越界的情况
                if(ans1[i] + ans2[k-i] == temp)
                {
                    ans = k;
                    break;
                }
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
posted @ 2019-12-21 14:32  hezongdnf  阅读(164)  评论(0)    收藏  举报