牛客网编程基础9-11

9.最高分是多少

题目描述
老师想知道从某某同学当中,分数最高的是多少,现在请你编程模拟老师的询问。当然,老师有时候需要更新某位同学的成绩.
输入描述:
输入包括多组测试数据。
每组输入第一行是两个正整数N和M(0 < N <= 30000,0 < M < 5000),分别代表学生的数目和操作的数目。
学生ID编号从1编到N。
第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩
接下来又M行,每一行有一个字符C(只取‘Q’或‘U’),和两个正整数A,B,当C为’Q’的时候, 表示这是一条询问操作,他询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少
当C为‘U’的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。
输出描述:
对于每一次询问操作,在一行里面输出最高成绩.
示例1
输入

5 7
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 4 5
U 2 9
Q 1 5
输出

5
6
5
9

*分析:**STL里max_element时前面要加,并且第二个参数要为指定位置的下一个位置。

#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdlib>
using namespace std;

int main()
{
    int n,m,i,j,t1,t2,count=0;
    char y;
    while(cin>>n>>m)
    {
        vector<int> g(n+1);
        g[0]=0;
        for(i=1;i<n+1;i++)
            cin>>g[i];
        for(i=0;i<m;i++)
        {
            cin>>y>>t1>>t2;
            if(y=='U')
                g[t1]=t2;
            else
            {
                if(t1>t2)
                    swap(t1,t2);
                cout<<*max_element(g.begin()+t1,g.begin()+t2+1)<<endl;
            }
        }
    }
    return 0;
} 

10.最大子方阵

题目描述
有一个方阵,其中每个单元(像素)非黑即白(非0即1),请设计一个高效算法,找到四条边颜色相同的最大子方阵。
给定一个01方阵mat,同时给定方阵的边长n,请返回最大子方阵的边长。保证方阵边长小于等于100。
测试样例:
[[1,1,1],[1,0,1],[1,1,1]],3
返回:3

分析:最大子方阵的边长依次减一,最小为1。方阵的上下左右边都取该方阵的左上角点作为颜色标准,这样编码会比较方便。如果最初是4阶方阵,那判断本身是否满足,与mat[0][0]作比较。不满足则把范围扩大到左上角四个点,取三阶方阵与该四点作为各方阵的左上角点作比较。依次类推~

class SubMatrix {
public:
    int maxSubMatrix(vector<vector<int> > mat, int n) {
        // write code here
    int max_length=n;
    int i,j,k,flag;
    bool top,bottom,left,right;
    while( max_length>0 )
    {
        for(i=0;i<=n-max_length;i++) 
            for(j=0;j<=n-max_length;j++)
            {
                flag=mat[i][j];
                for(k=0;k<max_length;k++)
                {
                    if(mat[i][j+k]==flag)       //上边 
                        top=true;
                    else{
                        top=false;
                        break;
                    }
                    if(mat[i+max_length-1][j+k]==flag)      //下边 
                        bottom=true;
                    else{
                        bottom=false;
                        break;
                    }
                    if(mat[i+k][j]==flag)       //左边 
                        left=true;
                    else{
                        left=false;
                        break;
                    }
                    if(mat[i+k][j+max_length-1]==flag)      //右边 
                        right=true; 
                    else{
                        right=false;
                        break;
                    }
                }
                if(top&&bottom&&left&&right)
                {
                    //cout<<max_length;
                    return max_length; 
                }
            }
        max_length--;
    }  
    return 0; 
    }
};

11.整数对查找

题目描述
请设计一个高效算法,找出数组中两数之和为指定值的所有整数对。
给定一个int数组A和数组大小n以及需查找的和sum,请返回和为sum的整数对的个数。保证数组大小小于等于3000。
测试样例:
[1,2,3,4,5],5,6
返回:2

分析:首先,我们得对给出的数组进行排序,这样方便我们操作。然后分情况讨论:
第一,当A[i]+A[j] > sum,那就将j前移一位。
第二,当A[i]+A[j] < sum,那就将i后移一位。
第三,当A[i]+A[j]==sum,这里又得分情况啦,
如果A[i]==A[j], 比如12333345,x=j-i+1=4,则count(最后返回的值)应该加上x*(x-1)/2。
反之,那就数i之后有k1个同样的A[i],j之前有k2个同样的A[j],然后count加上k1*k2即可。

class FindPair {
public:
    int countPairs(vector<int> A, int n, int sum) {
        // write code hereint n=5,A[5]={1,2,3,4,5},sum=6;
    int length,i,j,s,x,count=0;
    length=A.size();
    if( length==0 || n<0 )
        return 0;
    //sort(A,A+5);
    sort(A.begin(),A.end());
    for(i=0,j=n-1;i<j;)
    {
        s=A[i]+A[j];
        if(s==sum)
        {
            if(A[i]==A[j])
            {
                x=j-i+1;
                count+=x*(x-1)/2;
                break;
            }
            else
            {
                int k1,k2;
                k1=i+1;
                while( k1<=j && A[i]==A[k1] )
                {
                    k1++;
                }
                k2=j-1;
                while( k2>=i && A[j]==A[k2] )
                {
                    k2--;
                }
                count+=(k1-i)*(j-k2);
                i=k1;
                j=k2;
            }
        }
        else if(s>sum)
        {
            j--;
        }
        else
        {
            i++;
        }   
    }
    return  count;
  }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值