codeforces #410 Div.2题解报告

来源:互联网 发布:进入国外网站软件 编辑:程序博客网 时间:2024/05/16 19:47
  • 本来一个人做着今下午的浙江省赛。第三题感觉枚举会爆内存就一顿敲代码,然后0ms过了,心态炸了不想做了,把昨晚的题解写一下。
  • 不得不说昨晚的出题人脑洞是真的大,结果惨不忍睹。

正题:

codeforces #410 Div.2题解报告

A. Mike and palindrome

题目描述:

Mike has a string s consisting of only lowercase English letters. He wants to change exactly one character from the string so that the resulting one is a palindrome.A palindrome is a string that reads the same backward as forward, for example strings "z", "aaa", "aba", "abccba" are palindromes, but strings "codeforces", "reality", "ab" are not.InputThe first and single line contains string s (1 ≤ |s| ≤ 15).OutputPrint "YES" (without quotes) if Mike can change exactly one character so that the resulting string is palindrome or "NO" (without quotes) otherwise.

分析:

  • A题就设坑啊,要求改变一个字符后可以为回文串,考虑几种情况:
    • ab->aa,aab->aaa,aaab->aaaa;
    • aba->aza;aabaa->aaxaa;
    • aabb//不可行;
    • aaabb//不可行;
  • 好的,所以就是前两种情况了。

代码:

#include<bits/stdc++.h>using namespace std;int main(){    char a[100];    scanf("%s",&a);    getchar();    int len=strlen(a),num,point=0;    num=len/2;    for(int i=0;i<num;i++)        if(a[i]!=a[len-1-i])            point++;    if(point==1)        printf("YES\n");    else if(!point && len&1)        printf("YES\n");    else        printf("NO\n");    return 0;}

B. Mike and strings

题目描述:

Mike has n strings s1, s2, ..., sn each consisting of lowercase English letters. In one move he can choose a string si, erase the first character and append it to the end of the string. For example, if he has the string "coolmike", in one move he can transform it into the string "oolmikec".Now Mike asks himself: what is minimal number of moves that he needs to do in order to make all the strings equal?InputThe first line contains integer n (1 ≤ n ≤ 50) — the number of strings.This is followed by n lines which contain a string each. The i-th line corresponding to string si. Lengths of strings are equal. Lengths of each string is positive and don't exceed 50.OutputPrint the minimal number of moves Mike needs in order to make all the strings equal or print  - 1 if    there is no solution.

分析:

  • 被H掉的一道题,没考虑数组内部是循环的。

  • 又是一个坑。

  • 以第0个串为基准,算出其它串相对于它需要移动的次数num[i]。

  • 求出第0个串操作l次能得到它本身(不一定为len,本题关键)。

  • 则第0个串操作k次,第i个串要与第0个串一致,需要操作(num[i]+k)%l。

  • 找到和最小的那组数的和即为answer。

代码:

#include<bits/stdc++.h>using namespace std;int getl(char *a)//找循环节{    int len = strlen(a);    for(int i=1;i<len;i++)    {        if(a[i]!=a[0]) continue;        int k=0;        while(k<len)        {            int m=(k+i)%len;            if(a[m]!=a[k]) break;            k++;        }        if(k==len)            return i;    }    return len;}int main(){    char a[50][55];    int ans[50][50];    int res[50];    memset(ans,0,sizeof(ans));    memset(res,0,sizeof(res));    int n,point=0,temp;    scanf("%d",&n);getchar();    for(int i=0;i<n;i++)    {        scanf("%s",a[i]);getchar();    }    if(n==1) {printf("0\n");return 0;}    int len=strlen(a[0]);    for(int i=1;i<n;i++)    {        temp=-1;        for(int j=0;j<len;j++)        {            if(a[i][j]!=a[0][0]) continue;            int k=0;            while(k<len)            {                int m=(k+j)%len;                if(a[i][m]!=a[0][k]) break;                k++;            }            if(k==len) { temp=1; ans[0][i]=j; res[0]+=j; break;}        }        if(temp==-1) { point=1; break; }//仍为-1表明,a[0]与a[i]不匹配,则无需再比较    }    if(point==1){printf("-1\n");return 0;}//同上注释    int l=getl(a[0]);//找循环节,本题关键    for(int i=1;i<l;i++)    {        ans[i][0]=i;        res[i]+=ans[i][0];        for(int j=1;j<n;j++)        {            ans[i][j]=(ans[i-1][j]+1)%l;            res[i]+=ans[i][j];        }    }    int mm=res[0];    for(int i=1;i<l;i++) mm=min(mm,res[i]);    printf("%d\n",mm);    return 0;}

C. Mike and gcd problem

题目描述:

Mike has a sequence A = [a1, a2, ..., an] of length n. He considers the sequence B = [b1, b2, ..., bn] beautiful if the gcd of all its elements is bigger than 1, i.e. .Mike wants to change his sequence in order to make it beautiful. In one move he can choose an index i (1 ≤ i < n), delete numbers ai, ai + 1 and put numbers ai - ai + 1, ai + ai + 1 in their place instead, in this order. He wants perform as few operations as possible. Find the minimal number of operations to make sequence A beautiful if it's possible, or tell him that it is impossible to do so.is the biggest non-negative number d such that d divides bi for every i (1 ≤ i ≤ n).InputThe first line contains a single integer n (2 ≤ n ≤ 100 000) — length of sequence A.The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 109) — elements of sequence A.OutputOutput on the first line "YES" (without quotes) if it is possible to make sequence A beautiful by performing operations described above, and "NO" (without quotes) otherwise.If the answer was "YES", output the minimal number of moves needed to make sequence A beautiful.

分析:

  • 非常有想法的一道题。首先这题是不会输出NO的。

  • 这个题的解法分为两种情况:

    • 1.当所有数的gcd>1时,输出0;
    • 2.当所有数的gcd=1时,则有以下操作:
      • a) ai,ai+1均为奇数,进行一次操作,ai - ai+1 和 ai + ai+1 均为偶数,gcd>1;
      • b) ai为奇数,ai+1为偶数,或ai为偶数,ai+1为奇数,进行一次操作,ai - ai+1 和 ai + ai+1均为奇数,变为a)情况。
  • 因此只需要将其变为偶数就可以使所有数的gcd=2,所以不存在输出NO的情况。

  • 只能将其变为2的原因根据我的理解为,变换后ai 与 ai+1 相差 2* ai+1 ,如要进行变换,必存在ai或ai+1为质数,则gcd只能为2或该质数,由于变换前互质,因此不存在gcd为质数的情况,所以只能为2。

  • 然后本题还要注意一个点,加法溢出,虽然在本题中并无影响,因为溢出不会改变奇偶性,但是为了操作简单,我们可以将所有数字变为1 2进行操作。

代码:

#include <bits/stdc++.h>using namespace std;const int maxn = 100000+5;int a[maxn],n;int main(){    scanf("%d",&n);    int g=0;    for(int i=0;i<n;i++)    {        scanf("%d",&a[i]);        g=__gcd(g,a[i]);        if(a[i]%2==1) a[i]=1;        else a[i]=0;    }    if(g!=1) return printf("YES\n0\n")*0;    int res=0;    for(int i=0;i<n;i++)    {        if(i==n-1 && a[i])            res+=2;        else if(a[i] && a[i+1])            res+=1,a[i]=0,a[i+1]=0;        else if(a[i] && !a[i+1])            res+=2,a[i]=0,a[i+1]=0;    }    printf("YES\n");    printf("%d\n",res);    return 0;}

D. Mike and distribution

题目描述:

Mike has always been thinking about the harshness of social inequality. He's so obsessed with it that sometimes it even affects him while solving problems. At the moment, Mike has two sequences of positive integers A = [a1, a2, ..., an] and B = [b1, b2, ..., bn] of length n each which he uses to ask people some quite peculiar questions.To test you on how good are you at spotting inequality in life, he wants you to find an "unfair" subset of the original sequence. To be more precise, he wants you to select k numbers P = [p1, p2, ..., pk] such that 1 ≤ pi ≤ n for 1 ≤ i ≤ k and elements in P are distinct. Sequence P will represent indices of elements that you'll select from both sequences. He calls such a subset P "unfair" if and only if the following conditions are satisfied: 2·(ap1 + ... + apk) is greater than the sum of all elements from sequence A, and 2·(bp1 + ... + bpk) is greater than the sum of all elements from the sequence B. Also, k should be smaller or equal to  because it will be to easy to find sequence P if he allowed you to select too many elements!Mike guarantees you that a solution will always exist given the conditions described above, so please help him satisfy his curiosity!InputThe first line contains integer n (1 ≤ n ≤ 105) — the number of elements in the sequences.On the second line there are n space-separated integers a1, ..., an (1 ≤ ai ≤ 109) — elements of sequence A.On the third line there are also n space-separated integers b1, ..., bn (1 ≤ bi ≤ 109) — elements of sequence B.OutputOn the first line output an integer k which represents the size of the found subset. k should be less or equal to .On the next line print k integers p1, p2, ..., pk (1 ≤ pi ≤ n) — the elements of sequence P. You can print the numbers in any order you want. Elements in sequence P should be distinct.

分析:

  • 这题又是考想法。
  • 将下标以a为基准降序排序,然后在两两比较,选b[num[i]]跟b[num[i+1]]中较大值,然后加入ans。
  • 需要注意的是,本题给k的范围为 n/2 +1 ,所以num[0]可以直接取。
  • 然后讲一下这种思路的正确性,由于要找到a[p1]+a[p2]+…+a[pk]>a[1]+…+a[n],则将a降序排序后,由于取到max(a),和最小的情况便为 num[1,3,5,…..2k-1],根据a[num[i]]>a[num[i+1]],这样做是一定满足条件的。
  • 所以只需要考虑b的元素取法,要得到k个元素使它们的和大于所有元素的和,由于k是大于len/2的,所以我只要在两两元素中取较大的一个元素,就一定满足。
  • 有点有意思的地方,可以看下官方标程里sort的cmp写法,用了c++11的匿名函数,get到一个知识点。

代码:

#include <bits/stdc++.h>using namespace std;const int maxn = 1e5+5;int a[maxn],b[maxn],num[maxn],n,k;vector <int> res;bool cmp(const int &i,const int &j){    return a[i]>a[j];}int main(){    scanf("%d",&n);    k=n/2+1;    for(int i=1;i<=n;i++)  num[i]=i;    for(int i=1;i<=n;i++)  scanf("%d",&a[i]);    for(int j=1;j<=n;j++)  scanf("%d",&b[j]);    sort(num+1,num+n+1,cmp);    res.push_back(num[1]);    for(int i=2;i<=n;i+=2)    {        if(i==n) { res.push_back(num[i]); break; }        if( b[num[i]] >=b[num[i+1]])            res.push_back(num[i]);        else            res.push_back(num[i+1]);    }    printf("%d\n",k);    printf("%d",res[0]);    for(int i=1;i<res.size();i++)        printf(" %d",res[i]);    printf("\n");}

E. Mike and code of a permutation

题目描述:

Mike has discovered a new way to encode permutations. If he has a permutation P = [p1, p2, ..., pn], he will encode it in the following way:Denote by A = [a1, a2, ..., an] a sequence of length n which will represent the code of the permutation. For each i from 1 to n sequentially, he will choose the smallest unmarked j (1 ≤ j ≤ n) such that pi < pj and will assign to ai the number j (in other words he performs ai = j) and will mark j. If there is no such j, he'll assign to ai the number  - 1 (he performs ai =  - 1).Mike forgot his original permutation but he remembers its code. Your task is simple: find any permutation such that its code is the same as the code of Mike's original permutation.You may assume that there will always be at least one valid permutation.InputThe first line contains single integer n (1 ≤ n ≤ 500 000) — length of permutation.The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ n or ai =  - 1) — the code of Mike's permutation.You may assume that all positive values from A are different.OutputIn first and only line print n numbers p1, p2, ..., pn (1 ≤ pi ≤ n) — a permutation P which has the same code as the given one. Note that numbers in permutation are distinct.

分析:

  • 后面补,给的题解看的我头疼。
0 0
原创粉丝点击