• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
nannandbk
博客园    首页    新随笔    联系   管理    订阅  订阅
Codeforces Round 903 (Div. 3) ABCDE

Codeforces Round 903 (Div. 3)ABCDE

A. Don't Try to Count

题意:复制\(s\)串若干遍,是否能在\(s\)串中找到\(t\)串。

思路:直接暴力,注意不要超限,会MLE

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
int ns[30],nt[30];
int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    int t; cin>>t;
    while(t--)
    {
        int n,m; cin>>n>>m;
        string s,t; cin>>s>>t;
        
        for(int i = 0;i <= 30; i++)
            ns[i] = nt[i] = 0;
        for(int i = 0;i < n; i++)
            ns[s[i]-'a']++;
        for(int i = 0;i < m; i++)
            nt[t[i]-'a']++;

        bool ok = true;
        for(int i = 0;i < 26; i++)if(nt[i]&&!ns[i]){
            ok = false;
            break;
        }

        if(!ok)
            cout<<"-1\n";
        else{
            bool ok = false;
            int cnt = 0;
            while(1)
            {   
                if(cnt>10)break;
                if(s.find(t) != string::npos)
                {
                    ok = true;
                    break;
                }
                s = s + s;
                cnt++;
            }
            if(ok)cout<<cnt<<"\n";
            else cout<<"-1\n";
        }
    }
    return 0;
}

B. Three Threadlets

题意:给你3根绳子,问你能否在3刀以内(可以为0刀),使得所有绳子一样长。

思路:分析一下,我们最终一定会变成当前最短的,如果变不成,那一定不行。因为如果不变成当前最短的,那么意味着当前最短的要被切,那么其他的不可能在剩余2刀之内切成一样,除非原本三个都和最短的一样长。

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;

int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    int t; cin>>t;
    while(t--)
    {
        ll a,b,c;
        cin>>a>>b>>c;
        ll minn = min({a,b,c});
        if(a%minn||b%minn||c%minn)
            cout<<"No\n";
        else{
            int ans = 0;
            if(a!=minn)
                ans += a/minn-1;
            if(b!=minn)
                ans += b/minn-1;
            if(c!=minn)
                ans += c/minn-1;

            if(ans>3)
                cout<<"No\n";
            else cout<<"Yes\n";

        }
    }
    return 0;
}

C. Perfect Square

题意:给你一个初始矩阵,问你如果要该矩阵旋转90°之后和原来的一样,最少要操作多少次。每次操作可以选择一个让他变成下一个(z的话就不变了)

思路:旋转后\(a[i][j],a[j][N-i+1],a[N-i+1][N-j+1],a[N-j+1][i]\)是要一样的,那么,我们考虑变成这四个中最大的(因为只能往大的变),统计答案即可。

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
char s[1010][1010];
int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    int t; cin>>t;
    while(t--)
    {
        int n; cin>>n;
        for(int i = 1;i <= n; i++)
            for(int j = 1;j <= n; j++)
                cin>>s[i][j];
        ll ans = 0;
        int m = n/2;
        /*
            a[i][j] -> a[j][N-i+1]
             ↑             ↓
            a[N-j+1][i]<-a[N-i+1][N-j+1]
        */
        for(int i = 1;i <= m; i++)
        {
            for(int j = i; j < n-i+1; j++)
            {
                char a[4] = {s[i][j],s[j][n-i+1],s[n-i+1][n-j+1], s[n-j+1][i]};
                char mx = a[0];

                for(int k = 1;k < 4; k++)
                    mx = max(mx,a[k]);
                for(int k = 0;k < 4; k++)
                    ans += mx-a[k];
            }
        }
        cout<<ans<<"\n";
        
    }

    return 0;
}
    

D. Divide and Equalize

题意:给你一个数组\(a\)包含\(n\)个正整数。每次你可以选择任意两个元素\(a_i,a_j\),然后让\(a_i/x,aj*x\)(这里\(x\)整除\(a_i\))。问能否使得所有元素都变得一样。

思路:根据唯一分解定理,我们对每个数进行质因数分解。最后我们的每种质因子一定要可以平均分配才能使得所有数一样。

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
int a[N];
map<int,int>mp;
void primer(ll x)
{
    for (ll i = 2; i <= x / i; i++)
    {
        if (x % i == 0)
        {
            int s = 0;
            while (x % i == 0)
            {
                x = x / i;
                s++;
            }
            mp[i]+=s;
        }
    }
    if (x > 1)mp[x]++;
}

int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    int t; cin>>t;
    while(t--)
    {
        mp.clear();
        int n; cin>>n;
        for(int i = 1;i <= n; i++)
            cin>>a[i],primer(a[i]);

        bool ok = true;
        // for(auto [x,c]:mp)
        //     cout<<x<<" "<<c<<"\n";
        for(auto [x,c]:mp)if(c%n&&x!=1){
            ok = false;
            break;
        }

        if(ok)cout<<"Yes\n";
        else cout<<"No\n";

    }
    return 0;
}

E. Block Sequence

题意:给你一个序列\(a\)长度为\(n\)。我们定义:我们可以把元素分成第一个元素长度的块的叫做美丽数组。问最少操作多少次能变得美丽。

思路:dp。我们知道,当前的和后面的有关,我们考虑倒着dp。

定义:\(dp[i]\):\(i~n\)最少删多少个是美丽的。

转移:

考虑删掉:\(dp[i] = dp[i+1]+1\)

考虑保留:\(if(i+a[i]\le n) dp[i] = dp[i+a[i]+1]\)

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
ll a[N],dp[N];
int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    int t; cin>>t;
    while(t--)
    {
        int n; cin>>n;
        for(int i = 1;i <= n; i++)
            cin>>a[i];
        dp[n] = 1,dp[n+1] = 0;
        for(int i = n-1;i >= 1;i--)
        {
            dp[i] = dp[i+1]+1;//删除
            if(a[i]<=n-i)//保留
                dp[i] = min(dp[i],dp[i+a[i]+1]);
        }
        cout<<dp[1]<<"\n";
    }
    return 0;
}

posted on 2023-11-10 16:52  nannandbk  阅读(42)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3