s赛5 青白黄砖全题解

A 凯撒密码
定义一个字符串由全部的合法字符按顺序组成 在复制一遍形成一个环
使用字符串的rfind(优先位于后面的相同字符)函数找到现在字符的位置在进行变换

class Solution {
public:
    /**
     * 解密密文
     * @param str string字符串 密文
     * @param d int整型 偏移量
     * @return string字符串
     */
    string decode(string str, int d) {
        string t="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        t+=t;
        string s;
        for(int i=0;i<str.size();i++) s+=t[t.rfind(str[i])-d];
        return s;
    };

};

B 完全平方数
大于一千的数在取模后与小于一千的某个数的数值是一样的 所以我们只需要遍历1-999就行

class Solution {
public:
    /**
     * 
     * @param x int整型 
     * @return bool布尔型
     */
    bool solve(int x) {
        for(int i=1;i<=999;++i)
        {
            if((i*i)%1000==x) return true;
        }
        return false;
    }
};

C 排队
用一个优先队列存储排队的时间顺序 在用归并排序统计逆序对的个数即为答案

class Solution {
public:
       #define ll long long
       priority_queue<ll,vector<ll>, greater<ll>>b;
       ll s[111111];
       void Union(int L,int R,int mid,ll &sum)
       {
        ll q[111111];
        int k=1,l=L,r=mid+1;
        while(l<=mid&&r<=R)
        {
            if(s[l]<=s[r])
            {
                q[k++]=s[l++];
            }
            else
            {
                sum+=mid+1-l;
                q[k++]=s[r++];
            }
        }
        while(l<=mid)q[k++]=s[l++];
        while(r<=R)q[k++]=s[r++];
        for(int i=L,j=1;i<=R;i++,j++)s[i]=q[j];
        return;
      }
      void merge(int l,int r,ll &sum)
      {
        if(l==r)return;
        int mid=(l+r)/2;
        merge(l,mid,sum);
        merge(mid+1,r,sum);
        Union(l,r,mid,sum);
       }
      ll getNumValidPairs(int n, int m, vector<int>& a) {
          // write code here
        for(int i=0;i<m;++i)b.push(0);
        for(int i=1;i<=n;++i)
        {
         ll k=b.top()+a[i-1];
         s[i]=k;
         b.pop();
         b.push(k);
        }
        ll ans=0;
        merge(1,n,ans);
        return ans;
    }
};

D 牛牛的字符串
用标记数组存储是否到过 没到过的字符进行+K的比较并标记
在比较过程中用一个数组统计字符的个数和大小 每一个新的字符都能与前面比他小的字符进行交换 这样答案就出来了

class Solution {
public:
    /**
     * 
     * @param s string字符串 s.size() <= 1e5
     * @param k int整型 k <= s.size()
     * @return int整型
     */
    int turn(string s, int k) {
        // write code here
        int ans=0,v[100005]={0};
        int len=s.length();
        for(int i=0;i<len;++i)
        {
            if(v[i]) continue;
            int q[30]={0};
            for(int j=i;j<len;j+=k)
            {
                v[j]=1;
                int tmp=s[j]-'a'+1;
                for(int kk=1;kk<tmp;++kk)
                    ans+=q[kk];
                q[tmp]++;
            }
        }
        return ans;
    }
};

E 下棋
先将棋盘存入数组 在二维前缀和统计大小 在由题目所给式子来进行累加得到答案

class Solution {
public:
    /**
     * 求每一步后的总分数,所有分数都对1,000,000,007取模
     * @param n int整型 棋盘大小
     * @param query int整型vector 每次掷出的点数的列表
     * @return int整型vector
     */
    #define ll long long
    int mod=1000000007;
    ll a[2005][2005],sum[2005][2005];
    int x[2005*2005],y[2005*2005];
    vector<int> getScores(int n, vector<int>& q) 
    {
        // write code here
        vector<int> res;
        int cnt=1,i=1,j=1;
        while(cnt<=n*n)///将棋盘存入数组
        {
            for(;j<=n;++j)
            {
                if(j>n||a[i][j]) break;
                x[cnt]=i;
                y[cnt]=j;
                a[i][j]=cnt++;
            }
            j--,i++;
            for(;i<=n;++i)
            {
                if(i>n||a[i][j]) break;
                x[cnt]=i;
                y[cnt]=j;
                a[i][j]=cnt++;
            }
            i--,j--;
            for(;j>=1;--j)
            {
                if(j<1||a[i][j]) break;
                x[cnt]=i;
                y[cnt]=j;
                a[i][j]=cnt++;
            }
            j++,i--;
            for(;i>=1;--i)
            {
                if(i<1||a[i][j]) break;
                x[cnt]=i;
                y[cnt]=j;
                a[i][j]=cnt++;
            }
            i++,j++;
        }
        for(int i=1;i<=n;++i)///二维前缀和统计
        {
            for(int j=1;j<=n;++j)
            {
                sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];
            }
        }
        int idx=1;
        ll ans=0;
        for(int i=0;i<q.size();++i)///由题目的式子来累加
        {
            idx=(idx+q[i]-1)%(n*n)+1;
            for(int j=max(x[idx]-q[i]+1,1);j<=min(x[idx]+q[i]-1,n);++j)
            {
                ans=(ans+sum[j][n]-sum[j-1][n])%mod;
            }
            for(int j=max(y[idx]-q[i]+1,1);j<=min(y[idx]+q[i]-1,n);++j)
            {
                ans=(ans+sum[n][j]-sum[n][j-1])%mod;
            }
            for(int j=max(x[idx]-q[i]+1,1);j<=min(x[idx]+q[i]-1,n);++j)
            {
                for(int k=max(y[idx]-q[i]+1,1);k<=min(y[idx]+q[i]-1,n);++k)
                {
                    ans=((ans-a[j][k])%mod+mod)%mod;
                }
            }
            res.push_back((int)ans);
        }
        return res;
    }   
};

具体的解法在程序中体现qwq

全部评论

相关推荐

我是小红是我:学校换成中南
点赞 评论 收藏
分享
10-25 00:32
香梨想要offer:感觉考研以后好好学 后面能乱杀,目前这简历有点难
点赞 评论 收藏
分享
评论
1
1
分享
牛客网
牛客企业服务