每个测试输入包含1个测试用例,第一行包括两个整数 N 和 D : 3 <= N <= 100 1 <= D <= N 接下来有N行,每行N个数字d: 0 <= d <= 100
输出一个整数,表示找到的和的最大值
4 2 87 98 79 61 10 27 95 70 20 64 73 29 71 65 15 0
193
#include<iostream>
#include<string>
using namespace std;
int maps[105][105];
int map1[105][105];
int map2[105][105];
int map3[105][105];
int map4[105][105];
/*初始化四个数组,分别表示水平相加,竖直相加,主对角线,次对角线
对于水平相加的数组,a[i][j]表示第i行前j个元素相加,竖直相加的数组类似
对于主对角线的数组,a[i][j]表示第i行第j列所在的元素所在的对角线的叠加,次对角线类似
这样做是在计算的时候减少了一层循环,减少时间复杂度
*/
void init(int n){
///水平相加
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
map1[i][j]=map1[i][j-1]+maps[i][j];
}
}
///竖直相加
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
map2[i][j]=map2[i-1][j]+maps[i][j];
}
}
///主对角线相加
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
map3[i][j]=map3[i-1][j-1]+maps[i][j];
}
}
///次对角线相加
for(int i=1;i<=n;i++){
for(int j=n;j>=1;j--){
map4[i][j]=map4[i-1][j+1]+maps[i][j];
}
}
}
int main()
{
int N,D;
cin>>N>>D;
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
cin>>maps[i][j];
}
}
init(N);
int ans=0;
int r1,r2,r3,r4;
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
r1=r2=r3=r4=0;
if(j>=D){
r1=map1[i][j]-map1[i][j-D];
}
if(i>=D){
r2=map2[i][j]-map2[i-D][j];
}
if(i>=D&&j>=D){
r3=map3[i][j]-map3[i-D][j-D];
///这里次对角线的处理,比较特殊,需要对于j向后平移一个
r4=map4[i][j-D+1]-map4[i-D][j+1];
}
ans=max(ans,max(max(r1,r2),max(r3,r4)));
}
}
cout<<ans<<endl;
return 0;
}
import java.util.*;
public class Main{
public static void main(String args[]){
Scanner in=new Scanner(System.in);
int n=in.nextInt();
int d=in.nextInt();
int a[][]=new int[n][n];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
a[i][j]=in.nextInt();
}
}
int max1=Math.max(heng(a,n,d),shu(a,n,d));
int max2=Math.max(zuoxie(a,n,d),youxie(a,n,d));
System.out.println(Math.max(max1,max2));
}
static int heng(int[][] a,int n,int d){
int max=0;
for(int j=0;j<n;j++){
int l=0,r=d-1;int sum=0;
for(int i=0;i<d;i++){
sum+=a[j][i];
}
max=Math.max(sum,max);
while(r+1<n){
max=Math.max(max,sum+a[j][++r]-a[j][l]);sum+=a[j][r]-a[j][l];l++;
}
}
return max;
}
static int shu(int[][] a,int n,int d){
int max=0;
for(int j=0;j<n;j++){
int l=0,r=d-1;int sum=0;
for(int i=0;i<d;i++){
sum+=a[i][j];
}
max=Math.max(sum,max);
while(r+1<n){
max=Math.max(max,sum+a[++r][j]-a[l][j]);sum+=a[r][j]-a[l][j];l++;
}
}
return max;
}
static int zuoxie(int[][] a,int n,int d){
int max=0;
for(int j=0;j<=n-d;j++){
int l1=j,l2=0,r1=j,r2=0;int sum=0;
for(;r2<d;r2++,r1++){
sum+=a[r1][r2];
}
r2--;r1--;
max=Math.max(sum,max);
while(r1+1<n){
max=Math.max(max,sum+a[++r1][++r2]-a[l1][l2]);sum+=a[r1][r2]-a[l1][l2];l1++;l2++;
}
}
for(int j=1;j<=n-d;j++){
int l1=0,l2=j,r1=0,r2=j;int sum=0;
for(;r1<d;r2++,r1++){
sum+=a[r1][r2];
}
r2--;r1--;
max=Math.max(sum,max);
while(r2+1<n){
max=Math.max(max,sum+a[++r1][++r2]-a[l1][l2]);sum+=a[r1][r2]-a[l1][l2];l1++;l2++;
}
}
return max;
}
static int youxie(int[][] a,int n,int d){
int max=0;
for(int j=d-1;j<n;j++){
int l1=j,l2=0,r1=j,r2=0;int sum=0;
for(;r2<d;r2++,r1--){
sum+=a[r1][r2];
}
r2--;r1++;
max=Math.max(sum,max);
while(r1-1>=0){
max=Math.max(max,sum+a[--r1][++r2]-a[l1][l2]);sum+=a[r1][r2]-a[l1][l2];l1--;l2++;
}
}
for(int j=1;j<=n-d;j++){
int l1=n-1,l2=j,r1=n-1,r2=j;int sum=0;
for(;r1>=n-d;r2++,r1--){
sum+=a[r1][r2];
}
r2--;r1++;
max=Math.max(sum,max);
while(r2+1<n){
max=Math.max(max,sum+a[--r1][++r2]-a[l1][l2]);sum+=a[r1][r2]-a[l1][l2];l1--;l2++;
}
}
return max;
}
} | #include<iostream> usingnamespacestd; intmain() { intjie, num, array[10][10], k = 0; cin >> jie >> num; intright, low; intcount, out[100] = {0}; for(inti = 0; i < jie; ++i) { for(intj = 0; j < jie; ++j) { right = jie - i - num; low = jie - j - num; count = 0; if(right >= 0 && low >= 0) { while(num--) { count += array[i+num-1][j+num-1]; } out[k++] = count; } count = 0; if(right >= 0 && low < 0) { while(num--) { count += array[i][j + num - 1]; } out[k++] = count; } count = 0; if(right < 0 && low >= 0) { while(num--) { count += array[i+num-1][j]; } out[k++] = count; } } } intmax = out[0]; for(intm = 1; m < k; ++m) { if(out[m] > max) { max = out[m]; } } cout << max; return0; } |
//维护四个前缀和
#include <cstdio>
#include <cstring>
#include <algorithm>
usingnamespacestd;
intn, d, a[110][110], srow[110][110], scol[110][110], srd[110][110], sld[110][110];
intmain() {
scanf("%d%d", &n, &d);
for(inti = 1; i <= n; i++)
for(intj = 1; j <= n; j++)
scanf("%d", &a[i][j]);
for(inti = 1; i <= n; i++)
for(intj = 1; j <= n; j++) {
srow[i][j] = srow[i][j-1] + a[i][j];
scol[j][i] = scol[j][i-1] + a[i][j];
srd[i][j] = srd[i-1][j-1] + a[i][j];
sld[i][j] = sld[i-1][j+1] + a[i][j];
}
intans = 0;
for(inti = 1; i <= n; i++)
for(intj = 1; j <= n; j++) {
intli = i - d, lj = j - d, rj = j+d;
if(lj >= 0)
ans = max(ans, srow[i][j] - srow[i][lj]);
if(li >= 0)
ans = max(ans, scol[j][i] - scol[j][li]);
if(li >= 0 && lj >= 0)
ans = max(ans, srd[i][j] - srd[li][lj]);
if(li >= 0 && rj <= n+1)
ans = max(ans, sld[i][j] - sld[li][rj]);
}
printf("%d\n", ans);
return0;
}
#include <bits/stdc++.h>usingnamespacestd;intrl( vector<vector<int> > dp, intN, intD){intres = 0;for(inti = 0; i<N; i++){for(intj = 0; j<N-D+1; j++){inttmp = 0;for(intt = 0; t<D; t++){tmp += dp[i][j + t];}res = max(res, tmp);}}returnres;}inttb( vector<vector<int> > dp, intN, intD){intres = 0;for(inti = 0; i<N-D+1; i++){for(intj = 0; j<N; j++){inttmp = 0;for(intt = 0; t<D; t++){tmp += dp[i+t][j];}res = max(res, tmp);}}returnres;}intrl1( vector<vector<int> > dp, intN, intD){intres = 0;for(inti = 0; i<N-D+1; i++){for(intj = 0; j<N-D+1; j++){inttmp = 0;for(intt = 0; t<D; t++){tmp += dp[i+t][j + t];}res = max(res, tmp);}}returnres;}inttb1(vector<vector<int> > dp, intN, intD){intres = 0;for(inti = 0; i < N-D +1; i++){for(intj = N-1; j >= D -1; j--){inttmp = 0;for(intt = 0; t<D; t++){tmp += dp[i + t][j - t];}res = max(res, tmp);}}returnres;}intmain(){intN,D;while(cin>>N>>D){vector<vector<int> > dp;vector<int> v;intd;for(inti=0;i<N;i++){v.clear();for(intj=0;j<N;j++){cin>>d;v.push_back(d);}dp.push_back(v);}intmax1=rl(dp,N,D);intmax2=tb(dp,N,D);intmax3=rl1(dp,N,D);intmax4=tb1(dp,N,D);intres =max(max(max(max1,max2),max3),max4);cout<<res<<endl;}return0;}
//为什么用java写的人辣么少呢,,,
//这个感觉不是很难,就是有点复杂代码。。。
import java.util.Scanner;
/**
* Created by huali on 2018/5/25.
*/
public class Main {
// 在一个N*N的数组中寻找所有横,竖,左上到右下,右上到左下,
// 四种方向的直线连续D个数字的和里面最大的值
//输入描述:
//每个测试输入包含1个测试用例,第一行包括两个整数 N 和 D :
//3 <= N <= 100
//1 <= D <= N
//接下来有N行,每行N个数字d:
//0 <= d <= 100
//
//
//输出描述:
//输出一个整数,表示找到的和的最大值
//
//输入例子1:
//4 2
//87 98 79 61
//10 27 95 70
//20 64 73 29
//71 65 15 0
//
//输出例子1:
//193
public static void main(String []args)
{
Scanner sr = new Scanner(System.in);
while (sr.hasNext())
{
int N = sr.nextInt();
int D = sr.nextInt();
int [][]arr = new int[N][N];
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
arr[i][j] = sr.nextInt();
}
}
int max= 0;
for (int i = 0; i < N; ++i)
{
for (int start = 0; start <= N-D; ++start)
{
int sum=0;
for (int k = 0; k < D; ++k)
{
sum+=arr[i][start+k];
}
max = Math.max(max, sum);
}
}
for (int i = 0; i < N; ++i)
{
for (int start = 0; start <= N-D; ++start)
{
int sum=0;
for (int k = 0; k < D; ++k)
{
sum+=arr[start+k][i];
}
max = Math.max(max, sum);
}
}
for(int i=0;i<N;i++)
{
//按照列
for(int j=0;j<N;j++)
{
int temp = 0;
if(i+D-1>=0&&i+D-1<N&&j-D+1>=0&&j-D+1<N)
{
for (int k = 0; k < D; ++k)
{
temp += arr[i+k][j-k];
}
max = Math.max(max, temp);
}
}
//max = Math.max(max, temp);
}
for(int i=0;i<N;i++)
{
//按照列
//int temp = 0;
for(int j=0;j<N;j++)
{
int temp = 0;
if(i+D-1>=0&&i+D-1<N&&j+D-1>=0&&j+D-1<N)
{
for (int k = 0; k < D; ++k)
{
temp += arr[i+k][j+k];
}
max = Math.max(max, temp);
}
}
//max = Math.max(max, temp);
}
System.out.println(max);
}
sr.close();
}
} //使用积分图加快运算
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main()
{
using namespace std;
int n, d;
while (cin >> n >> d) {
vector<vector<int> > matrix(n, vector<int>(n, 0));
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> matrix[i][j];
int ans = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j <= n - d; j++) {
int ret = 0;
for (int k = j; k < j + d; k++) {
ret += matrix[i][k];
}
if (ret > ans)
ans = ret;
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j <= n - d; j++) {
int ret = 0;
for (int k = j; k < j + d; k++) {
ret += matrix[k][i];
}
if (ret > ans)
ans = ret;
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int ret = 0;
for (int k = 0; k < d; k++) {
if (i + k >= n || j + k >= n)
break;
ret += matrix[i + k][j + k];
}
if (ret > ans)
ans = ret;
}
}
for (int i = 0; i < n - d + 1; i++) {
for (int j = n - 1; j >= 0; j--) {
int ret = 0;
for (int k = 0; k < d; k++) {
if (i + k >= n || j - k < 0)
break;
ret += matrix[i + k][j - k];
}
if (ret > ans) {
ans = ret;
}
}
}
cout << ans << endl;
}
return 0;
}
#include <iostream>#include <string> using namespace std; int main() { int n, d, a[101][101]; scanf("%d%d", &n, &d); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { scanf("%d", &a[i][j]); } } int ans = 0; for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { int temp; if (n - j >= d) { //横 temp = 0; for (int k = j; k < j + d; ++k) { temp += a[i][k]; } ans = max(temp, ans); } if (n - i >= d) { //竖 temp = 0; for (int k = i; k < i + d; ++k) { temp += a[k][j]; } ans = max(ans, temp); } if (n - i >= d && n - j >= d) { //左上到右下 temp = 0; for (int k = i, l = j; k < i + d, l < j + d; ++k, ++l) { temp += a[k][l]; } ans = max(ans, temp); } if (n - i >= d && j >= d - 1) { //右上到左下 temp = 0; for (int k = i, l = j; k < i + d, l > j - d; ++k, --l) { temp += a[k][l]; } ans = max(ans, temp); } } } cout << ans << endl; return 0; }
卡最后一个案例 的注意题意 ,连续的D个数,也就是不包括小于D个数的答案, 当然讲道理D个数的和
大于D-1 个数的和,算不算都无所谓,但是不包括有负数的情况,所以会出现极端情况,D-1个数的
和大于D个数和,所以避免计算小于D个数的和,这样不会卡最后一个案例
#include<bits/stdc++.h>
using namespace std;
const int N=100;
int arr[N][N];
int main()
{
int i,j,k;
int n,d;
int sum=0;
int ans[N][N];
cin>>n>>d;
for(i=0; i<n; i++){
for(j=0; j<n; j++){
cin>>arr[i][j];
}
}
int m1 = 0;//横行
for(i=0; i<n; i++){
for(j=0; j<n; j++){
sum = 0;
for(k=0; k<d; k++){
if(j+k>=n) break;
sum += arr[i][j+k];
}
if(m1 < sum){
m1 = sum;
}
}
}
//cout<<m1<<endl;
int m2=0; //竖列
for(i=0; i<n; i++){
for(j=0; j<n; j++){
sum = 0;
for(k=0; k<d; k++){
if(j+k>=n) break;
sum += arr[j+k][i];
}
if(m2 < sum){
m2 = sum;
}
}
}
//cout<<m2<<endl;
int m3=0; //左上到右下
for(i=0; i<n; i++){
for(j=0; j<n; j++){
sum = 0;
for(k=0; k<d; k++){
if(i+k>= n || j+k >= n) break;
sum += arr[i+k][j+k];
}
if(m3<sum){
m3 = sum;
}
}
}
//cout<<m3<<endl;
int m4=0; //右上到左下
for(i=0; i<n-d+1; i++){
for(j=n-1; j>=0; j--){
sum = 0;
for(k=0; k<d; k++){
if(i+k>=n || j-k<0 ) break;
sum += arr[i+k][j-k];
}
//cout<<sum<<" ";
if(m4<sum){
m4 = sum;
}
}
}
//cout<<m4<<endl;
int ma=0;
ma = max(ma,m1);
ma = max(ma,m2);
ma = max(ma,m3);
ma = max(ma,m4);
cout<<ma<<endl;
return 0;
}
import java.util.Scanner;
public class Main{
public static void main(String args[]){
Scanner scan = new Scanner(System.in);
int N = 0;
int D = 0;
N = scan.nextInt();
D = scan.nextInt();
int[][] nums = new int[N][N];
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
nums[i][j] = scan.nextInt();
}
}
int max = 0;
//确定各方向的第一个值的索引
for(int k = 0; k < N; k++){
//确定各方向连续D个值的开始索引
for(int begin = 0; begin <= N-D; begin++){
//横
int hsum = 0;
//竖
int ssum = 0;
//左上到右下1
int lsum1 = 0;
//左上到右下2
int lsum2 = 0;
//右上到左下1
int rsum1 = 0;
//右上到左下2
int rsum2 = 0;
//开始求各方向连续D个数的和
for(int m = 0; m < D; m++){
hsum += nums[k][begin+m];
ssum += nums[begin+m][k];
if((k+D+begin) <= N){
lsum1 += nums[k+begin+m][begin+m];
//避免1和2重复求k=0时的和
if(k != 0){
lsum2 += nums[begin+m][k+begin+m];
rsum2 += nums[k+begin+m][N-1-begin-m];
}
}
if((N-k-begin-D) >= 0){
rsum1 += nums[m+begin][N-1-k-begin-m];
}
}
if(hsum > max)
max = hsum;
if(ssum > max)
max = ssum;
if(lsum1> max)
max = lsum1;
if(lsum2 > max)
max = lsum2;
if(rsum1 > max)
max = rsum1;
if(rsum2 > max)
max = rsum2;
}
}
System.out.println(max);
}
}
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int d = input.nextInt();
int arr[][] = new int[n][n];
for (int x = 0; x < n; x++) {
for (int y = 0; y < n; y++) {
arr[x][y] = input.nextInt();
}
}
int max = 0;
//从每个点出发,都有四种可能,到左下角的和、到右下角的和、下垂直方向的和、右水平方向的和
//每次计算完这四个方向的和,就让top指针自增,即向右移动到下一个,该行全部计算完后,再让left下移到下一行,同时top从0开始计算
for (int left = 0; left < n; left++) {
for (int top = 0; top < n; top++) {
if (top + 1 - d >= 0 && left - 1 + d < n) {
int temp = leftLine(arr, left, top, d);
max = max > temp ? max : temp;
}
if (top - 1 + d < n && left - 1 + d < n) {
int temp = rightLine(arr, left, top, d);
max = max > temp ? max : temp;
}
if (top - 1 + d < n) {
int temp = horizontalLine(arr, left, top, d);
max = max > temp ? max : temp;
}
if (left - 1 + d < n) {
int temp = verticalLine(arr, left, top, d);
max = max > temp ? max : temp;
}
}
}
System.out.println(max);
}
static int leftLine(int[][] arr, int left, int top, int d) {
int result = 0;
for (int x = 0; x < d; x++) {
result += arr[left][top];
left++;
top--;
}
return result;
}
static int rightLine(int[][] arr, int left, int top, int d) {
int result = 0;
for (int x = 0; x < d; x++) {
result += arr[left][top];
left++;
top++;
}
return result;
}
static int horizontalLine(int[][] arr, int left, int top, int d) {
int result = 0;
for (int x = 0; x < d; x++) {
result += arr[left][top];
top++;
}
return result;
}
static int verticalLine(int[][] arr, int left, int top, int d) {
int result = 0;
for (int x = 0; x < d; x++) {
result += arr[left][top];
left++;
}
return result;
}
}
#include <iostream>
(720)#include <string>
#include <algorithm>
using namespace std;
int main() {
int N, D;
while (cin >> N >> D) {
const int n = 100;
int input[n][n];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cin>>input[i][j];
}
}
int mx = 0;
// 按行
for (int i = 0; i < N; i++) {
for (int j = 0; j < N-D+1; j++) {
int temp = 0;
int t = 0;
while (t < D) {
temp += input[i][j + t];
t++;
}
mx = max(mx, temp);
}
}
// 按列
for (int i = 0; i < N; i++) {
for (int j = 0; j < N - D + 1; j++) {
int temp = 0;
int t = 0;
while (t < D) {
temp += input[j + t][i];
t++;
}
mx = max(mx,temp);
}
}
// 左上到右下
for (int i = 0; i < N-D+1; i++) {
for (int j = 0; j < N - D + 1; j++) {
int temp = 0;
int t = 0;
while (t < D) {
temp += input[i + t][j + t];
t++;
}
mx = max(mx,temp);
}
}
// 右上到左下
for (int i = 0; i<N-D+1; i++) {
for (int j = N-1; j >D-2; j--) {
int temp = 0;
int t = 0;
while (t < D) {
temp += input[i + t][j - t];
t++;
}
mx = max(mx,temp);
}
}
// total
cout << mx << endl;
}
return 0;
} 思路:对于矩阵的每一点,计算它的横,竖,右下,左下的D个数之和是否比当前最大值大,如果是则替换当前的最大值。check函数是为了判断点(x,y)是否越界
#include<iostream>
using namespace std;
bool check(int x, int y, int N);
int main()
{
//输入N和D
int N, D;
cin >> N >> D;
//输入数据
int **matrix = new int*[N];
for (int i = 0; i < N; i++) {
matrix[i] = new int[N];
}
//初始化矩阵
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cin >> matrix[i][j];
}
}
//计算每一点开始的最大值
int max = matrix[0][0];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
//计算横
if (check(j + D-1, i, N)) {
int count = 0;
for (int k = 0; k < D; k++) {
count += matrix[i][j + k];
}
max = count > max ? count : max;
}
//计算竖
if (check(i + D - 1, j, N)) {
int count = 0;
for (int k = 0; k < D; k++) {
count += matrix[i+k][j];
}
max = count > max ? count : max;
}
//左上到右下
if (check(i + D - 1, j+D-1, N)) {
int count = 0;
for (int k = 0; k < D; k++) {
count += matrix[i + k][j+k];
}
max = count > max ? count : max;
}
//右上到左下
if (check(i + D - 1, j - D + 1, N)) {
int count = 0;
for (int k = 0; k < D; k++) {
count += matrix[i + k][j - k];
}
max = count > max ? count : max;
}
}
}
cout << max;
system("pause");
return 0;
}
bool check(int x,int y,int N) {
return (x >= 0 && x < N && 0 <= y&&y < N);
}