Codeforces Round #786 (Div. 3) A-F题解

A. Number Transformation

题意:给定两个数x和y,询问是否存在a和b使得x*ba=y

思路:暴力求解

#include 

using namespace std;

int fastpow(int a,int n)
{
    int res=1;
    while(n)
    {
        if(n&1)
        {
            res*=a;
        }
        a*=a;
        n>>=1;
    }
    return res;
}
int main()
{
    int t;
    for(cin>>t;t;t--)
    {
        int x,y;
        cin>>x>>y;
        if(y<x||y%x!=0)
        {
            cout<<"0 0"<<endl;
            continue;
        }
        else
        {
            int kk=y/x;
          //  cout<
            for(int i=1;i<=100;i++)
            {
                for(int j=1;j<=100;j++)
                {
                    if(fastpow(j,i)==kk)
                    {
                        cout<<i<<" "<<j<<endl;
                        goto o;
                    }
                }
            }
        }
        o:;
    }
    return 0;
}

B. Dictionary

题意:给定两个字母用来表示数字,两个字母一定不相同。ab表示1,ac表示2,az表示25
ba表示26 bc表示27以此类推,问你任意两个字母表示什么数字

思路:暴力求解

#include 

using namespace std;
int main()
{
    map<string,int> mp;
    int cnt=1;
    for(char a='a';a<='z';a++)
    {
        for(char b='a';b<='z';b++)
        {
            if(a==b)
                continue;
            string s="";
             s+=a;s+=b;
            mp[s]=cnt++;
        }
    }
    int t;
    for(cin>>t;t;t--)
    {
        string s;
        cin>>s;
        cout<<mp[s]<<endl;
    }
    return 0;
}

C. Infinite Replacement

题意:给定一个只包含一种字符‘a’的字符串s和一个字符串t,求将s中的任意字符‘a’替换后,算上原来的字符s一共能产生多少不同的字符串,如果无限多输出-1。

思路:分类讨论,如果t中含有字符‘a’有两种情况
1.t的长度为1,那么答案就是1
2.t的长度不是1,答案就是-1

t中不含有‘a’,设s的长度为k,答案就是2k

我没开longlong wa了一发

#include 

using namespace std;

int main()
{
    int k;
    for(cin>>k;k;k--)
    {
        string s,t;
        cin>>s>>t;
        char a=s[0];
        int len1=s.length();
        int len2=t.length();
        bool falg=false;
        for(int i=0;i<len2;i++)
        {
            if(t[i]==a)
            {
                falg=true;
                break;
            }
        }
        if(falg&&len2>1)
        {
            cout<<-1<<endl;
            continue;
        }
        else if(falg&&len2==1)
        {
            cout<<1<<endl;
            continue;
        }
        else
        {
            cout<<(1ll<<len1)<<endl;
        }
    }
    return 0;
}

D. A-B-C Sort

题意:
给定数组a,我们先把a用操作1装到数组b中
操作1:不断拿取数组a的最后一个元素放到数组b的中间位置,中间位置为x,如果b长度为奇数可以放在x/2+1或者x/2处
然后再用操作2把数组b放到数组c中
操作2:不断拿数组b的中间元素放到c的末尾处
如果c能够形成不严格递增序列输出YES否则输出NO

思路:模拟一下元素的存取发现,实际上A到C只不过是相邻元素可以交换位置,注意奇偶讨论

#include 

using namespace std;
const int N = 2e5+100;
int a[N];
int b[N];
int main()
{
    int k;
    for(cin>>k;k;k--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
        }
        if(n&1)
        for(int i=2;i<=n-1;i+=2)
        {
            if(a[i]>a[i+1])
            {
                 swap(a[i],a[i+1]);
            }
        }
        else
        {
            for(int i=1;i<=n-1;i+=2)
            {
                if(a[i]>a[i+1])
                {
                    swap(a[i],a[i+1]);
                }
            }
        }
        bool falg=true;
        for(int i=1;i<=n-1;i++)
        {
            if(a[i]>a[i+1])
            {
                falg=false;
            }
        }
        if(falg)
        {
            cout<<"YES"<<endl;
        }
        else
        {
            cout<<"NO"<<endl;
        }
    }
    return 0;
}

E. Breaking the Wall

题意:给定一个数组,每次可以选择一个位置x,a[x]的值-2,a[x-1]和a[x+1]的值-1

求让至少两个地方的数值小于等于0需要几次操作

思路:
首先思考答案可能产生在哪
1.间隔相邻的a[x+1]和a[x-1]
2.相邻的a[x]和a[x+1]
3.不相邻的a[i]和a[j]

对于第一种情况,我们显然让两个的和相加除二向上取整就好了

低于第三种情况,我们让最小的两个分别除二向上取整就好了

对于第二种情况,我们有a[x]位置除二向上取整,a[x+1]+1除二向上取整,(这两种是因为打击的连带效应,如果a[x]或者a[x]+1比相邻的大两倍那么自然把这一位置消除相邻位置也消除了)

a[i]+a[i+1]+2除二向上取整(这是处理相邻且不是两倍以上关系的情况)三种情况

#include 

using namespace std;
int a[200000+100];
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    int ans=1e9;
    for(int i=1;i<=n-2;i++)
    {
        ans=min(ans,a[i]/2+a[i+2]/2+1);
    }
    for(int i=1;i<=n-1;i++)
    {
        ans=min(ans,max({(a[i]+1)/2,(a[i+1]+1)/2,(a[i]+a[i+1]+2)/3}));
    }
    sort(a+1,a+1+n);
    ans=min((a[1]+1)/2+(a[2]+1)/2,ans);
    cout<<ans<<endl;
    return 0;
}

F. Desktop Rearrangement
模拟题,很简单没什么好说的。

#include 

using namespace std;
char a[1100][1100];
int n,m,q;
int sum,col[1100];
int main()
{
   cin>>n>>m>>q;
   for(int i=1;i<=n;i++)
   {
       for(int j=1;j<=m;j++)
       {
           cin>>a[i][j];
           if(a[i][j]=='*')
           {
              sum++;
              col[j]++;
           }
       }
   }
   while(q--)
   {
       int i,j;
       cin>>i>>j;
       if(a[i][j]=='*')
       {
           sum--;
           col[j]--;
       }
       if(a[i][j]=='*')
           a[i][j]='.';
       else
           a[i][j]='*';
       if(a[i][j]=='*')
        {
            col[j]++;
            sum++;
        }
        int cnt=sum/n;
        int r=sum%n;
        int t=0;
        for(int j=1;j<=cnt;j++)
        {
            t+=col[j];
        }
        for(int i=1;i<=r;i++)
        {
            if(a[i][cnt+1]=='*')
                t++;
        }
        cout<<sum-t<<endl;
   }
    return 0;
}

G. Remove Directed Edges
明天补,,

你可能感兴趣的:(算法刷题,算法,c++,思维,模拟,数学)