Codeforces Round 903 (Div. 3)

题目链接

A.

按题意模拟
字符串find函数
if(x.find(s)==string::npos)//没找到

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N=1e5+10;
#define inf 0x3f3f3f3f

void solve() {
    int n,m;cin>>n>>m;
    string x,s;cin>>x>>s;
    int cnt=0;
    while(x.size()<100){
        if(x.find(s)==string::npos){
            x=x+x;cnt++;
        }else{
            cout<<cnt<<'\n';
            return ;
        }
    }
    cout<<"-1\n";
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int left=1;
    cin>>left;
    while(left--){
        solve();
    }
}

B.

先排序,再判大数是不是小数的整数倍,若不是则NO
再计算出割断的次数,小等于3才是YES

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N=1e5+10;
#define inf 0x3f3f3f3f

void solve() {
    int a[5];
    for(int i=1;i<=3;i++)cin>>a[i];
    sort(a+1,a+1+3);
    int cnt=0;
    for(int i=2;i<=3;i++){
        if(a[i]%a[1]!=0){
            cout<<"NO\n";return ;
        }
        cnt+=a[i]/a[1]-1;
    }
    if(cnt<=3)cout<<"YES\n";
    else cout<<"NO\n";
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int left=1;
    cin>>left;
    while(left--){
        solve();
    }
}

C.

找到点(i,j)旋转后的其他3个位置,取最大值
算出操作次数即可

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N=1e3+10;
#define inf 0x3f3f3f3f

int g[N][N];
void solve() {
    int n;cin>>n;
    char c;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            cin>>c;
            g[i][j]=c-'a';
        }
    int cnt=0;
    for(int i=1;i<=n/2;i++){
        for(int j=1;j<=n/2;j++){
            int ma=max({g[i][j],g[n-j+1][i],g[j][n-i+1],g[n-i+1][n-j+1]});
            int tmp=g[i][j]+g[n-j+1][i]+g[j][n-i+1]+g[n-i+1][n-j+1];
            cnt+=ma*4-tmp;
        }
    }
    cout<<cnt<<'\n';
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int left=1;
    cin>>left;
    while(left--){
        solve();
    }
}

D.

考虑把所有数都进行质因数分解(分成最小单位)
然后看每种质因数是否都有n的整数倍个,这样一定能通过若干操作后使每个数相同
类似于守恒

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N=1e5+10;
#define inf 0x3f3f3f3f

void solve() {
    int n;cin>>n;
    map<int,int>mp;
    for(int i=1,x;i<=n;i++){
        cin>>x;
        //cout<<"x="<<x<<'\n';
        mp[1]++;
        for(int j=2;j*j<=x;j++){
            if(x%j==0){
                while(x%j==0){
                    mp[j]++;
                    x/=j;
                    //cout<<j<<'\n';
                  //  cout<<"x="<<x<<'\n';
                }
                //cout<<"x="<<x<<' '<<"j="<<j<<'\n';
            }
        }
        //cout<<'\n';
        if(x>1)mp[x]++;
    }
    for(auto t:mp){
        if(t.second%n==0)continue;
        cout<<"NO\n";return ;
    }
    cout<<"YES\n";
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int left=1;
    cin>>left;
    while(left--){
        solve();
    }
}

E.

从后往前dp,看当前数作为区间开头能否更优,否则就删掉

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N=2e5+10;
#define inf 0x3f3f3f3f

int a[N];
void solve() {
    int n;cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    vector<int>dp(n+10,0);
    dp[n]=1;dp[n+1]=0;
    for(int i=n-1;i>=1;i--){
        if(i+a[i]<=n){
            dp[i]=min(dp[i+a[i]+1],dp[i+1]+1);
        }else{
            dp[i]=dp[i+1]+1;
        }
    }
    cout<<dp[1]<<'\n';
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int left=1;
    cin>>left;
    while(left--){
        solve();
    }
}

F.

首先,最远考虑直径,再最小考虑直径的中间值
问题转化成距离最远的两个标记点的一半
那么就是标记点之间的直径的一半

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N=2e5+10;
#define inf 0x3f3f3f3f

int n,k;
vector<int>vis;
vector<vector<int>>g;
int d1,d2;
int dep_d1,dep_d2;
void dfs1(int u,int fa,int dep){
    if(vis[u]&&dep>dep_d1){
        dep_d1=dep;
        d1=u;
    }
    for(int i=0;i<g[u].size();i++){
        int y=g[u][i];
        if(y==fa)continue;
        dfs1(y,u,dep+1);
    }
}
void dfs2(int u,int fa,int dep){
    if(vis[u]&&dep>dep_d2){
        dep_d2=dep;
        d2=u;
    }
    for(int i=0;i<g[u].size();i++){
        int y=g[u][i];
        if(y==fa)continue;
        dfs2(y,u,dep+1);
    }
}
void solve() {
    dep_d1=0;dep_d2=0;
    cin>>n>>k;
    vis=vector<int>(n+1);
    g=vector<vector<int>>(n+1);
    for(int i=1,x;i<=k;i++){
        cin>>x;
        vis[x]++;
    }
    for(int i=1,u,v;i<n;i++){
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    if(n==1||k==1){
        cout<<"0\n";return ;
    }
    if(n==2){
        cout<<"1\n";return ;
    }
    for(int i=1;i<=n;i++){
        if(vis[i]){
            dfs1(i,0,1);
//     cout<<"i="<<i<<'\n';
            break;
        }
    }
    dfs2(d1,0,1);
  //  cout<<"d1="<<d1<<' '<<"d2="<<d2<<'\n';
    cout<<dep_d2/2<<'\n';
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int left=1;
    cin>>left;
    while(left--){
        solve();
    }
}

posted @ 2024-02-18 13:45  WW爆米花  阅读(2)  评论(0编辑  收藏  举报