河南工程学院百知杯竞赛题部分题解

基建手游

题目描述

森林探险后小明打算在家中宅一阵子,他迷上了一款基建手游。
在浩瀚的布鲁克西大陆上,有一个神秘的王国,城主小明可以选择在这个王国里圈出一块占地K*K的正方形作为自己的城池,小明希望你选出一块合适的位置,使得他的城池土地价值和最大。

输入

第一行三个整数N,M,K,表示大陆的宽和长以及占地正方形的边长。
接下来有N行,每行M个整数,表示大陆上每个地块的价值,价值可能为负数。
1=<N, M<=1000, 1=<k<=min(N, M)

输出

一行两个整数X,Y表示小明城池左上角的坐标

样例输入

3 4 1
1 2 3 1
-1 9 0 2
2 0 1 1

样例输出

2 2
#include<iostream>

using namespace std;

int n,m,k;

int a[1005][1005],b[1005][1005];

int main() {

    scanf("%d%d%d",&n,&m,&k);

    for(int i=1; i<=n; i++) {

        for(int j=1; j<=m; j++) {

            scanf("%d",&a[i][j]);

            b[i][j]=b[i-1][j]+b[i][j-1]-b[i-1][j-1]+a[i][j];     //前缀和

            /*1 1 1 1     

             1 1 1 1

             1 1 1 1

             1 1 1 1 */

             

/*1 2 3 4

 2 4 6 8

 3 6 9 12

 4 8 12 16*/

              

        }

    }

    int maxn=-99999999;

    int xx,yy;

    k--;

    for(int i=1; i<=n-k; i++) {

        for(int j=1; j<=m-k; j++) {

            int sum=b[i+k][j+k]-b[i+k][j-1]-b[i-1][j+k]+b[i-1][j-1];

            if(sum>maxn) {

                xx=i,yy=j;

                maxn=sum;

            }

        }

    }

    cout<<xx<<' '<<yy;

}

本题考查前缀和,代码中间已经列举了最简单的前缀和,帮助同学们快速理解。

前缀和:

核心代码:b[i][j]=b[i-1][j]+b[i][j-1]-b[i-1][j-1]+a[i][j];这是二维数组中的前缀和

对于此题,开始使用的是暴力求解,很明显时间超限,然后对此类题进行了百度求解,才知道了前缀和。

敏感的小明同学

题目描述

小明是一个对数字非常敏感的人,当他看到某个特定的数字p (1<=p<=9)时就会兴奋一下,现在给你一个数值区间( l , r ),问你当小明看到这个区间内所有的数字时会兴奋多少下?(例如 l=2,r=22,p=2时,小明会兴奋6下,l=2,12,20,21时各兴奋一下,22兴奋两下)

输入

首先輸入一个整数 t,以下再输入t行数据。(t<=10000)
每行输入三个整数 l , r , p. (1<=l<=r<=10^8 ,1<=p<=9)

输出

输出t行,每行一个整数表示小明兴奋的次数。

样例输入

1
2 22 2

样例输出

6

#include<iostream>
using namespace std;
int l,r;
int p;
int f(int x) {
    int a=x,t=1,s=0;
    while(x) {
        s+=x/10*t;
        if(x%10>p)s+=t;
        else if(x%10==p)s+=a%t+1;
        x/=10;
        t*=10;
    }
    return s;
}
 
int main() {
    int t;
    cin>>t;
    while(t--) {
        cin>>l>>r>>p;
        cout<<f(r)-f(l-1)<<endl; 
    }
    return 0;
 
}

对于此题,意思就是从数字r到l,数字p一共出现多少次;

这道题的思路是从数的个位上出现的p全部找出来,然后再找十位上的p,以此类推;

举例:

 0   222   2

第一步 s+=x/10*t; 1-10...210..220,二在个位上出现一共有22次

(x%10==p)s+=a%t+1; 这次还得加一 共23次,这次是222的最后一个二

然后x除十,t乘十

第二步 判断十位上的s+=x/10*t   20...29  120..129;  共计20次

(x%10==p)s+=a%t+1;   这又是三次 220 221 222 记住只看十位上的二;

然后x除十,t乘十

第三步 判断百位上的二 (x%10==p)s+=a%t+1    200.....222    注意只看百位上的二

22+1=23次

所以一共23+23+23=69次;

森林探险

题目描述

小明是个方向感极弱的人,为了证明自己,他打算进入森林探险。
他的朋友小红给了他一个写满坐标的地图,如果他按照地图上的点一通过并且最终记住自己向左转动(不包括向后转动)了几次的话,就算小明胜利。
望着地图上密密麻麻的坐标轴,小明头都大了,但是聪明的他立刻想到了你:算法神犇!
你可以帮助他完成这一挑战吗?

输入

第一行一个整数n(3<=n<=1000)
下面n行每行包含两个数,为每个点的坐标x,y(0=x<=1000,0<=y<=1000),第一个点为起始点,小明行走的顺序为给出的点的顺序.

输出

一个整数。(小明向左转动的次数,不包括向后转动)
样例输入

6
0 0
0 1
1 1
1 2
2 2
2 0

样例输出

1

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stack>
#include<algorithm>
#include<math.h>
using namespace std;
struct P {
    int x;
    int y;
} feng[2000],p1,p2;
double judge(P p1,P p2,P p3) {
    return ((p2.x-p1.x)*(p3.y-p2.y)-(p2.y-p1.y)*(p3.x-p2.x));   //叉乘向量a叉乘向量b等于向量a的模乘向量b的模乘sin&;&是角度值,向量a叉乘向量b一向量a为x轴逆时针旋转是&的值 
}
int main() {
    int n;
    scanf("%d",&n);
    for(int i=0; i<n; i++) {
        scanf("%d%d",&feng[i].x,&feng[i].y);
    }
    int count=0;
    for(int i=2; i<n; i++) {
        if(judge(feng[i-2],feng[i-1],feng[i])>0)count++;    //第一步没方向 从第三步开始算 
    }
    printf("%d\n",count);
    return 0;
}

对于此题   主要考二维向量叉积的几何意义

叉积的几何意义有三:

1、A*B=|A|·|B|·sinα.

其中α表示A到B的夹角,用以判断该角度是正或者负。这个结论可用于四个点中任意三个点构成的三角形,判断另外一个点是否在三角形中,那么四个点构成三个向量叉积的结果就能判断。

2、A*B=x1*y2-x2*y1.

得到的结果应该是向量,但是取其模可以用于由A和B构成的平行四边形的面积,进而可以得到两个三角形的面积。

3、A*B=x1*y2-x2*y1.

得到的结果为一个向量,这个向量垂直于向量A和B。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值