首页 > 其他分享 >Codeforces Round 903 (Div. 3)

Codeforces Round 903 (Div. 3)

时间:2023-11-28 14:27:34浏览次数:28  
标签:903 int Codeforces cin -- while solve Div dp

Codeforces Round 903 (Div. 3)

A. Don't Try to Count

大概题意给你两个字符串a,b。a串可进行的操作为将整个a串复制到之前的a串后面(直接用a+a即可),然后看操作多少次可以让b串变为a串的子串如果不能就输出-1。

#include <iostream>
using namespace std;
string a,b;
void solve()
{
    int n,m;
    cin>>n>>m;
    cin>>a>>b;
    int cnt=0;
    while(n<m)
    {
        a=a+a;
        n<<=1;
        cnt++;
    }
    for(int i=0;i<n;++i)
    {
        bool pd=1;
        for(int j=i;j<i+m;++j)
        {
            if(a[j]!=b[j-i])
            {
                pd=0;
                break;
            }
        }
        if(pd)
        {
            cout<<cnt<<endl;
            return ;
        }
    }
    a=a+a;
    n<<=1;
    cnt++;
    for(int i=0;i<n;++i)
    {
        bool pd=1;
        for(int j=i;j<i+m;++j)
        {
            if(a[j]!=b[j-i])
            {
                pd=0;
                break;
            }
        }
        if(pd)
        {
            cout<<cnt<<endl;
            return ;
        }
    }


    cout<<-1<<endl;
}
int main() {
    int t;
    cin>>t;
    while(t--) {
        solve();
    }
    return 0;
}

B. Three Threadlets

题意:给三个数,分开他们使得剩下的为相同的

思路:三次分法,可以不完全用,所以只需要考虑最差的情况,将三个数排序为max,min,mid。如果三个数相等直接输出“YES”,如果三个数不相等的话那么就不能分min,如果mid也可以不分的话那么就有这两种情况
$$
max:mid:min=3:2:1(三次都用)/2:2:1(只用两次)
$$
如果mid=min那么只有max需要分那么就有比例为
$$
max:mid:min=4:1:1/3:1:1/2:1:1
$$

#include <iostream>
using namespace std;
void solve(){
    int a,b,c;
    cin>>a>>b>>c;
    if(a==b&&b==c) {
        cout<<"YES"<<"\n";
        return ;
    }int ma=a,mi=a;
    ma=max(ma,b);
    ma=max(ma,c);
    mi=min(mi,b);
    mi=min(mi,c);
    int mid=a+b+c-mi-ma;
    if(ma==2*mi&&mid==2*mi) {
        cout<<"YES"<<"\n";
        return ;
    }if(mid==mi&&ma==3*mi){
        cout<<"YES"<<"\n";
        return ;
    }if(ma==3*mi&&mid==2*mi) {
        cout<<"YES"<<"\n";
        return ;
    }if(mid==mi&&ma==2*mi){
        cout<<"YES"<<"\n";
        return ;
    }if(mid==mi&&ma==4*mi){
        cout<<"YES"<<"\n";
        return ;
    }
    cout<<"NO"<<"\n";
}
int main() {
    int t;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

C. Perfect Square

题意:有一个正方形矩阵,我们对其的操作一次为将一个字母++,当这个字母变成'z'时就不会再改变了,问多少次之后我们旋转90°之后和原来的矩阵重合

思路:一共有四种(90/360),我们可以求出这四个坐标中最大的,然后剩下的++记作一次操作

#include <bits/stdc++.h>
using namespace std;
char mp[1010][1010];
void solve(){
    int m;
    cin>>m;
    long long int res=0;
    for(int i=1;i<=m;i++){
        for(int j=1;j<=m;j++){
            cin>>mp[i][j];
        }
    }
    for(int i=1;i<=m/2;i++){
        for(int j=1;j<=m/2;j++){
            int ma=max(mp[i][j],max(mp[m-j+1][i],max(mp[m-i+1][m-j+1],mp[j][m-i+1])));
            res+=ma*4-mp[i][j]-mp[m-j+1][i]-mp[m-i+1][m-j+1]-mp[j][m-i+1];
        }
    }
    cout<<res<<endl;
}
int main()
{
    int t;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

D. Divide and Equalize

题意:操作:找到一个数x使得ai=ai/x;aj=aj/x;要求:所有数相等

思路:这个变化会使他的乘积没有变化,故我们可知他们的乘积为一个数的n次方,那么他的因数个数应该为n的倍数。

板子:质因数分解

void divide(int x)
{
    for (int i = 2; i <= x / i; i ++ )
        if (x % i == 0)
        {
            int s = 0;
            while (x % i == 0) x /= i, s ++ ;
            cout << i << ' ' << s << endl;
        }
    if (x > 1) cout << x << ' ' << 1 << endl;
    cout << endl;
}
#include <bits/stdc++.h>
using namespace std;
void solve(){
    int n;
    cin>>n;
    map<int,int> q;
    for(int j=0;j<n;j++){
        int x;
        cin>>x;
        for (int i = 2; i <= x / i; i ++ )
            if (x % i == 0)
            {
                int s = 0;
                while (x % i == 0) x /= i, s ++ ;
                q[i]+=s;
            }
        if (x > 1) q[x]++;
    }
    for(auto x:q){
        if(x.second%n!=0){
            cout<<"NO"<<"\n";
            return ;
        }
    }
    cout<<"YES"<<"\n";
}
signed main() {
    int t;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

E. Block Sequence

题意:操作:删除一个数;要求:让数列分成一块一块的(什么叫块:假设你a[i]=x,那么a[i]~a[i+x-1]为一个块)

1.把自身直接删了dp[i]=dp[i-1]+1;

2.假设左边已经有一个完美的块,要使整个序列都为完美,只需要后面也为完美块,假设后面的数<a[i],dp[i]=d[i+1]+1;如果相等dp[i]=0,如果后面的数>a[i]那么dp[i]=ap[i+a[i]+1];

#include <bits/stdc++.h>
using namespace std;
const int MAX=1e6+10;
int dp[MAX],arr[MAX];
void solve()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>arr[i];
    }
    dp[n + 1] = 0;
    for(int i = n; i >= 0; i --)
    {
        if(arr[i] + i > n) dp[i] = dp[i + 1] + 1;
        else if(arr[i] + i == n) dp[i] = 0;
        else dp[i] = dp[i + arr[i] + 1];
        dp[i] = min(dp[i], dp[i + 1] + 1);
    }
    cout << dp[0] << '\n';
}
int main()
{
    int t;
    cin>>t;
    while (t--){
        solve();
    }
    return 0;
}

F. Minimum Maximum Distance

题意:求min(max(顶点到所有标记点距离))

思路:树上任一点到其他点最远的距离即为到树的直径的两个端点中的一个的距离,跑两遍bfs求一下两个端点,最后再求所有最大值中的最小值即可

板子:bfs

queue<int> q;
st[1] = true; // 表示1号点已经被遍历过
q.push(1);

while (q.size())
{
    int t = q.front();
    q.pop();

    for (int i = h[t]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!st[j])
        {
            st[j] = true; // 表示点j已经被遍历过
            q.push(j);
        }
    }
}
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 400010;
vector<int> v[N];
int dist[N], f[N];
int st[N];
int n, k;

int bfs(int u)
{
    for (int i = 1; i <= n; i++)dist[i] = -1;
    queue<int> q;
    q.push(u);
    dist[u] = 0;

    while (q.size())
    {
        int t = q.front();
        q.pop();
        for (auto i : v[t])
        {
            int j = i;
            if (dist[j] == -1)
            {
                dist[j] = dist[t] + 1;
                q.push(j);
            }
        }
    }

    int ans = -1;
    for (int i = 1; i <= n; i++)
    {
        if (st[i] && (ans == -1 || dist[i] > dist[ans]))
        {
            ans = i;
        }
    }
    return ans;
}
void solve()
{
    cin >> n >> k;
    for (int i = 1; i <= n; i++)
    {
        v[i].clear();
    }
    for (int i = 1; i <= n; i++)st[i] = 0;
    for (int i = 1; i <= k; i++)
    {
        int x;
        cin >> x;
        st[x] = 1;
    }
    int m = n - 1;
    while (m--)
    {
        int a, b;
        cin >> a >> b;
        v[a].push_back(b);
        v[b].push_back(a);
    }

    int a = bfs(1);
    int b = bfs(a);
    for (int i = 1; i <= n; i++)f[i] = dist[i];
    bfs(b);

    for (int i = 1; i <= n; i++)
    {
        f[i] = max(f[i], dist[i]);
    }
    int minans = 1e18;
    for (int i = 1; i <= n; i++)
    {
        minans = min(minans, f[i]);
    }
    cout << minans << endl;
}

signed main()
{
    int t;
    cin>>t;
    while (t--)
    {
        solve();
    }

}

标签:903,int,Codeforces,cin,--,while,solve,Div,dp
From: https://www.cnblogs.com/bbbbear/p/17861857.html

相关文章

  • Codeforces Round 894 (Div. 3)
    CodeforcesRound894(Div.3)A.GiftCarpet题意:判断一列一个字母有没有“vika”思路:挨个枚举每一列#include<bits/stdc++.h>usingnamespacestd;charmp[25][25];charx[]={'v','i','k','a'};voidsolve(){intm,n;cin>>......
  • Codeforces Round 911 (Div. 2) D. Small GCD
    题目链接:https://codeforces.com/contest/1900/problem/D对于已经排序好的数组\(a\),我们需要计算:\[\sum_{i=1}^n\sum_{j=i+1}^ngcd(a_i,a_j)*(n-j)\]由于\(\sum_{d|n}\phi(d)=n\),因此:\[\gcd(a_i,a_j)=\sum_{d|a_i,d|a_j}\psi(d)\]代入可得:\[\sum_{i=1}^n\su......
  • CodeforcesDS1
    CodeforcesDS1CF387EGeorgeandCards(2200)Problem给出一个\(1\)到\(n\)的排列(输入中的数组\(p\)),并给出一个长为\(k\)的数组\(b\),要求从\(p\)中删去\(n-k\)个元素后得到数组\(b\)。删除操作的定义:选取一个区间\([l,r]\),删去其中最小的元素,并获得\(r-l......
  • CodeforcesDP1
    CodeforcesDP1CF833BTheBakery(2200)Problem将一个长度为\(n\)的序列\(a\)分为\(k\)段,使得总价值最大。一段区间的价值表示为区间内不同数字的个数。\(n\leq35000,k\leqmin(n,50),1\lea_i\len\)。Solution记\(f_{i,l,j}\)表示考虑前\(i\)个数,划分成\(......
  • Codeforces Round 911 (Div. 2) D
    D.SmallGCD题意给定数组\(a\),求出数组\(a\)中所有三元组中较小的两个元素的\(gcd\)的和.分析显然数组中元素的顺序不影响统计答案,为了方便先将数组排个序;枚举中间的元素\(a_j\),那么只有它前边的元素能与其产生贡献,它后边的元素个数就是这个贡献的倍数,下面考虑枚......
  • Codeforces Round 911 (Div. 2)
    CodeforcesRound911(Div.2)A-CoverinWater解题思路:如果存在三个以上相邻的格子需要填,那么答案为二,否则有多少空格答案为多少。代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;typedefpair<int,int>pii;#definefifirst#definese......
  • Codeforces Round 911 (Div. 2) A-C
    CodeforcesRound911(Div.2)A.CoverinWater题意:有n个单元格,有的空着有的被堵住,可以做两种操作:给一个空着的单元格放入水;将单元格的水移到另一个单元格。并且,若一个单元格左右两边都有水,它也会自动充满水。所有空着的单元格都要充满水,求最少的放入水的次数思路:若存在三......
  • CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!)
    20231127A.JaggedSwaps题意是:给你一个数组进行无数次的操作问你能不能单调思路:通过观察发现进行操作大的一定会被放在后面,所以一定会单调,但是操作是从2开始的,所以下表1的地方一定要是1usingnamespacestd;inta[20];voidsolve(){intn;cin>>n;for(in......
  • Codeforces Round 911 (Div. 2)
    A-CoverinWater三个连续的.就可以造出无限水,这时直接输出\(2\),否则输出区间长度和。SubmissionB-LauraandOperations每次操作不会改变不需要的两个数的个数的和的奇偶性,而当这个和为偶数的时候,通过若干操作一定可以全部变成另一个。SubmissionC-Anji'sBinary......
  • 汇编div的注意
    无符号除法32位模式下,DIV(无符号除法)指令执行8位、16位和32位无符号数除法,结果以余数和商的方式表现。格式如下:DIV8位寄存器或内存DIV16位寄存器或内存DIV32位寄存器或内存被除数除数商余数AXreg/mem8ALAHDX:AXreg/mem16AXDXEDX:EAXreg/mem32EAXEDX根据以上表格可......