牛客巅峰赛第五场 黄金&钻石&王者

题目链接:https://ac.nowcoder.com/acm/contest/6489

A-完全平方数的尾巴 

题意:判断给定的数x(0<=x<=999)是不是由某个完全平方数对1000取模的结果 

样例:

牛客巅峰赛第五场 黄金&钻石&王者_第1张图片

hint:该题就是打个表,给1到500(这个也可以更大)的平方对1000取模的值标记为true,然后直接输出a[i*i%1000]就好了。

AC代码: 

class Solution {
public:
    bool solve(int x) {
        // write code here
        bool a[1050]={false};
        for(int i=0;i<500;i++){
            a[(i*i)%1000]=true;
        }
        return a[x];
    }
};

B-牛牛的字符串

题意:长度为n的字符串,可以对Ai和Ak+i的位置进行交换 ,但是交换之后字符串字典序要变大,求最多交换次数。

样例: 

牛客巅峰赛第五场 黄金&钻石&王者_第2张图片

hint:就是将相差k的位置的元素全部取出放数组,然后求各个数组的正序个数就好了,1 2是正序,2 1是逆序。一下将用三种方法解答。 

方法一:用个二维数组now[i][26]存放第i个数组的字母以及个数 

AC代码:

class Solution {
public:
    int now[123456][26];
    int turn(string s, int k) {
        // write code here
        int cnt=0;
        for(int i=0;i

 方法二:先将字符串反转,归并排序求其相隔k元素的逆序数,正序=逆序+逆序

AC代码:

class Solution {
public:
    int a[123456],tmp[123456],cnt=0;
    void _merge(int l,int mid,int r){
        int p1=l,p2=mid+1;
        for(int i=l;i<=r;i++){
            if(p1<=mid&&(p2>r||a[p1]<=a[p2])){
                tmp[i]=a[p1];
                p1++;
            }else{
                tmp[i]=a[p2];
                p2++;
                cnt+=mid-p1+1;//逆序对
            }
        }
        for(int i=l;i<=r;i++)a[i]=tmp[i];
    }
    void msort(int l,int r){
        int mid=(l+r)>>1;
        if(l

方法三:用树状数组求正序对

AC代码:

class Solution
{
public:
    int a[55],ans=0;
    int lowbit(int x){
        return x&(-x);
    }
    void add(int x,int k){
        for(int i=x;i<50;i+=lowbit(i)){
            a[i]+=k;
        }
    }
    int getsum(int x){
        int ans=0;
        for(int i=x;i>0;i-=lowbit(i)){
            ans+=a[i];
        }
        return ans;
    }
    int turn(string s, int k)
    {
        // write code here
        for(int i=0;i

 

你可能感兴趣的:(树状数组,字符串)