Codeforces_798

Posted 冷暖知不知

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces_798相关的知识,希望对你有一定的参考价值。

A.暴力把每个位置的字符改成另外25个字符,判断是否回文。

技术分享
#include<bits/stdc++.h>
using namespace std;

string s;

int main()
{
    ios::sync_with_stdio(false);
    cin >> s;
    for(int i = 0;i < s.length();i++)
    {
        for(char j = a;j <= z;j++)
        {
            if(s[i] == j)   continue;
            string ss = s;
            ss[i] = j;
            string sss = ss;
            reverse(sss.begin(),sss.end());
            if(sss == ss)
            {
                cout << "YES" << endl;
                return 0;
            }
        }
    }
    cout << "NO" << endl;
    return 0;
 }
View Code

B.先判断是否都能变成相同串,若可以,则有一个特点,最后的串肯定与初始某个串相同,直接暴力就可以了。

技术分享
#include<bits/stdc++.h>
using namespace std;

int n,a[55][55];
string s[55];
map<string,int> mp;

int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    for(int i = 1;i <= n;i++)   cin >> s[i];
    int cnt = 0;
    for(int i = 0;i < s[1].length();i++)
    {
        string ss = s[1].substr(i)+s[1].substr(0,i);
        mp[ss] = 1;
    }
    for(int i = 2;i <= n;i++)
    {
        if(s[i].length() != s[1].length() || !mp.count(s[i]))
        {
            cout << -1 << endl;
            return 0;
        }
    }
    int ans =1e9;
    for(int i = 1;i <= n;i++)
    {
        int sum = 0;
        for(int j = 1;j <= n;j++)
        {
            if(i == j)  continue;
            for(int k = 0;k < s[i].length();k++)
            {
                string ss = s[j].substr(k)+s[j].substr(0,k);
                if(ss == s[i])
                {
                    sum += k;
                    break;
                }
            }
        }
        ans = min(ans,sum);
    }
    cout << ans << endl;
    return 0;
 }
View Code

C.这道题首先注意负数和0的gcd,可以用__gcd尝试一下。

先判断初始的gcd是否大于1,若大于1,直接YES。

否则,剩下的数我们只用考虑它们的奇偶性。

相邻两个分为4中情况:

  ①奇奇  直接操作这两个位置  ans+1

  ②偶偶  不用动

  ③奇偶  操作两次变成奇奇  ans+2

  ④偶奇  考虑到最少的操作次数,把奇与其后面的数操作,若奇已经是最后一位,偶奇操作两次,变成奇奇

技术分享
#include<bits/stdc++.h>
using namespace std;

int n,a[100005];

int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    cin >> a[1];
    int t = a[1];
    for(int i = 2;i <= n;i++)
    {
        cin >> a[i];
        t = __gcd(t,a[i]);
    }
    if(t > 1)
    {
        cout << "YES" << endl << 0 << endl;
        return 0;
    }
    int ans = 0;
    for(int i = 1;i < n;i++)
    {
        if(a[i]%2 && a[i+1]%2 == 0)
        {
            ans += 2;
        }
        else if(a[i]%2 && a[i+1]%2)
        {
            ans++;
            a[i+1]++;
        }
    }
    if(a[n]%2)  ans += 2;
    cout << "YES" << endl << ans << endl;
    return 0;
 }
View Code

D.我们对个数分奇偶。

若是奇数个:

  对A排序,A1对应下标加入,剩下偶数个数,两两分,每组取B中最大的那个下标。

若是偶数个:

  对A排序,A1对应下标加入,剩下n-2个跟上面相同操作,An对应下标加入。

这样操作的结果肯定是符合要求的。

技术分享
#include<bits/stdc++.h>
using namespace std;

int n,b[100005],c[100005];
struct xx
{
    int x,id;
    friend bool operator <(xx a,xx b)
    {
        return a.x > b.x;
    }
}a[100005];

vector<int> ans;

int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    long long sum1 = 0,sum2 = 0;
    for(int i = 1;i <= n;i++)   cin >> a[i].x,a[i].id = i;
    for(int i = 1;i <= n;i++)   cin >> b[i];
    sort(a+1,a+1+n);
    ans.push_back(a[1].id);
    for(int i = 2;i <= n;i += 2)
    {
        if(i == n)  ans.push_back(a[i].id);
        else
        {
            if(b[a[i].id] > b[a[i+1].id])   ans.push_back(a[i].id);
            else    ans.push_back(a[i+1].id);
        }
    }
    cout << ans.size() << endl;
    for(int i = 0;i < ans.size();i++)   cout << ans[i] << " ";
    cout << endl;
    return 0;
 }
View Code

 

另外还有种做法,随机大法,好厉害的样子。

技术分享
#include<bits/stdc++.h>
using namespace std;

int n,a[100005],b[100005],c[100005];

int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    long long sum1 = 0,sum2 = 0;
    for(int i = 1;i <= n;i++)   cin >> a[i],sum1 += a[i];
    for(int i = 1;i <= n;i++)   cin >> b[i],sum2 += b[i];
    int k = n/2+1;
    for(int i = 1;i <= n;i++)   c[i] = i;
    while(1)
    {
        long long x1 = 0,x2 = 0;
        for(int i = 1;i <= k;i++)
        {
            x1 += a[c[i]];
            x2 += b[c[i]];
        }
        if(x1*2 > sum1 && x2*2 > sum2)
        {
            cout << k << endl;
            for(int i = 1;i <= k;i++)   cout << c[i] <<  ;
            cout << endl;
            return 0;
        }
        random_shuffle(c+1,c+1+n);
    }
    return 0;
 }
View Code

 

以上是关于Codeforces_798的主要内容,如果未能解决你的问题,请参考以下文章

codeforces 798

Codeforces 798D Mike and distribution - 贪心

codeforces 798C Mike and gcd problem

Mike and palindrome CodeForces - 798A

codeforces 798c Mike And Gcd Problem

Codeforces-798C. Mike and gcd problem