Algorithm 在有条件的矩形中查找最大正方形
在给定高度和宽度的矩形中。我应该找到1最多的正方形,并在标准输出上打印1的数量,同样在同一个正方形中,2不能超过1的一半,即:((#of 1s)/2)>=(#of 2s)。 正方形始终至少有2x2大。 因此对于输入(前两个数字是高度和宽度): 正确答案是9。(正方形是5x5大,左上角在第二行第三列) 现在我设法写了一个程序来正确地完成这个任务,但是它太慢了 因此,我想问一个建议,如何编写算法,使它能够解决这个问题:在1秒以内(正确答案15),在4秒以内(正确答案556) 编辑:我忘了提到正方形,我指的只是正方形的周长(四边) 我的代码是这样工作的: 通过输入中的所有字段进行迭代,并通过从该字段开始的所有可能的正方形(从可能的最大正方形开始)进行迭代。然后我有一些条件,比如,当正方形的可能周长小于我在周长中找到的最大1时,我中断了迭代,等等。同样,当我试图从给定的场开始寻找正方形时,我记得前面正方形的上侧和左侧,然后将其减小(如果有1或2) 但这还不够,因为像这样的解决方案可以在1.5分钟内解决第二个输入,我需要在4秒钟内解决。 守则: 注:矿物代表1s,毒物代表2sAlgorithm 在有条件的矩形中查找最大正方形,algorithm,Algorithm,在给定高度和宽度的矩形中。我应该找到1最多的正方形,并在标准输出上打印1的数量,同样在同一个正方形中,2不能超过1的一半,即:((#of 1s)/2)>=(#of 2s)。 正方形始终至少有2x2大。 因此对于输入(前两个数字是高度和宽度): 正确答案是9。(正方形是5x5大,左上角在第二行第三列) 现在我设法写了一个程序来正确地完成这个任务,但是它太慢了 因此,我想问一个建议,如何编写算法,使它能够解决这个问题:在1秒以内(正确答案15),在4秒以内(正确答案556) 编辑:我忘了提到正方形,
#include <stdio.h>
#include <stdlib.h>
int maxMinerals;
void traverseforH(const int const *map, const int height, const int width) {
const int h1 = height - 1;
const int w1 = width - 1;
int lineOffset = 0;
for (int startY = 0; startY < h1; startY++) {
int yside = height - startY;
if (!(yside * 2 + (yside - 2)*2 > maxMinerals)) {
break;
}
for (int startX = 0; startX < w1; startX++) {
int xside = width - startX;
if (!(xside * 2 + (xside - 2)*2 > maxMinerals)) {
break;
}
int maxBoundl = width;
int maxBoundm = width;
if (startY + maxBoundm - height - startX > 0) {
maxBoundl = height;
maxBoundm = height;
if (startX - startY > 0) {
maxBoundl = maxBoundl + startY - startX;
} else {
maxBoundm = maxBoundm + startX - startY;
}
} else if (startY - startX > 0) {
maxBoundm = maxBoundm + startY - startX;
maxBoundl = maxBoundm;
maxBoundm = maxBoundm + startX - startY;
} else {
maxBoundl = maxBoundl + startY - startX;
}
int mBw = (maxBoundl - 1) * width;
int toxicsLeftSide = 0;
int mineralsLeftSide = 0;
int toxicsUpSide = 0;
int mineralsUpSide = 0;
int mw;
int lastMinerals = 0;
int toxics = 0;
int sidey = lineOffset + width;
for (int x = startX; x < maxBoundm; x++) {
mw = x + lineOffset;
if (map[mw] == 1) {
mineralsUpSide++;
lastMinerals++;
} else if (map[mw]) {
toxicsUpSide++;
toxics++;
}
mw = x + mBw;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
}
for (int y = startY + 1; y < maxBoundl - 1; y++) {
mw = startX + sidey;
if (map[mw] == 1) {
mineralsLeftSide++;
lastMinerals++;
} else if (map[mw]) {
toxicsLeftSide++;
toxics++;
}
mw = maxBoundm - 1 + sidey;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
sidey = sidey + width;
}
if (map[startX + mBw] == 1) {
mineralsLeftSide++;
} else if (map[startX + mBw]) {
toxicsLeftSide++;
}
int upsideData [2];
upsideData[0] = mineralsUpSide;
upsideData[1] = toxicsUpSide;
if (!(lastMinerals / 2.0 < toxics) && lastMinerals > maxMinerals) {
maxMinerals = lastMinerals;
}
mBw = mBw - width;
int noOfSquares;
if (xside < yside) {
noOfSquares = xside - 1;
} else {
noOfSquares = yside - 1;
}
for (int k = 1; k < noOfSquares; k++) {
int maxBoundy = maxBoundl - k;
int maxBoundx = maxBoundm - k;
if (!(((maxBoundx - startX)*2 + (maxBoundx - 2 - startX)*2) > maxMinerals)) {
break;
}
sidey = lineOffset + width;
lastMinerals = 0;
toxics = 0;
if (map[maxBoundx + lineOffset] == 1) {
mineralsUpSide--;
} else if (map[maxBoundx + lineOffset]) {
toxicsUpSide--;
}
if (map[startX + mBw + width] == 1) {
mineralsLeftSide--;
} else if (map[startX + mBw + width]) {
toxicsLeftSide--;
}
for (int x = startX + 1; x < maxBoundx; x++) {
mw = x + mBw;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
}
for (int y = startY + 1; y < maxBoundy - 1; y++) {
mw = maxBoundx - 1 + sidey;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
sidey = sidey + width;
}
int finalMinerals = lastMinerals + mineralsLeftSide + mineralsUpSide;
int finalToxics = toxics + toxicsLeftSide + toxicsUpSide;
if (!(finalMinerals / 2.0 < finalToxics) && finalMinerals > maxMinerals) {
maxMinerals = finalMinerals;
}
mBw = mBw - width;
}
}
lineOffset = lineOffset + width;
}
printf("%d\n", maxMinerals);
}
void traverseforW(int *map, const int height, const int width) {
int h1 = height - 1;
int w1 = width - 1;
int lineOffset = 0;
for (int startY = 0; startY < h1; startY++) {
int yside = height - startY;
if (!(yside * 2 + (yside - 2)*2 > maxMinerals)) {
break;
}
for (int startX = 0; startX < w1; startX++) {
int xside = width - startX;
if (!(xside * 2 + (xside - 2)*2 > maxMinerals)) {
break;
}
int maxBoundl = height;
int maxBoundm = height;
if (startX + maxBoundl - width - startY > 0) {
maxBoundl = width;
maxBoundm = width;
if (startX - startY > 0) {
maxBoundl = maxBoundl + startY - startX;
} else {
maxBoundm = maxBoundm + startX - startY;
}
} else if (startY - startX > 0) {
maxBoundm = maxBoundm + startX - startY;
} else {
maxBoundl = maxBoundl + startX - startY;
maxBoundm = maxBoundl;
maxBoundl = maxBoundl + startY - startX;
}
int mBw = (maxBoundl - 1) * width;
int toxicsLeftSide = 0;
int mineralsLeftSide = 0;
int toxicsUpSide = 0;
int mineralsUpSide = 0;
int mw;
int lastMinerals = 0;
int toxics = 0;
int sidey = lineOffset + width;
for (int x = startX; x < maxBoundm; x++) {
mw = x + lineOffset;
if (map[mw] == 1) {
mineralsUpSide++;
lastMinerals++;
} else if (map[mw]) {
toxicsUpSide++;
toxics++;
}
mw = x + mBw;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
}
for (int y = startY + 1; y < maxBoundl - 1; y++) {
mw = startX + sidey;
if (map[mw] == 1) {
mineralsLeftSide++;
lastMinerals++;
} else if (map[mw]) {
toxicsLeftSide++;
toxics++;
}
mw = maxBoundm - 1 + sidey;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
sidey = sidey + width;
}
if (map[startX + mBw] == 1) {
mineralsLeftSide++;
} else if (map[startX + mBw]) {
toxicsLeftSide++;
}
if (!(lastMinerals / 2.0 < toxics) && lastMinerals > maxMinerals) {
maxMinerals = lastMinerals;
}
mBw = mBw - width;
int noOfSquares;
if (xside < yside) {
noOfSquares = xside - 1;
} else {
noOfSquares = yside - 1;
}
for (int k = 1; k < noOfSquares; k++) {
int maxBoundy = maxBoundl - k;
int maxBoundx = maxBoundm - k;
if (!(((maxBoundx - startX)*2 + (maxBoundx - 2 - startX)*2) > maxMinerals)) {
break;
}
sidey = lineOffset + width;
lastMinerals = 0;
toxics = 0;
if (map[maxBoundx + lineOffset] == 1) {
mineralsUpSide--;
} else if (map[maxBoundx + lineOffset]) {
toxicsUpSide--;
}
if (map[startX + mBw + width] == 1) {
mineralsLeftSide--;
} else if (map[startX + mBw + width]) {
toxicsLeftSide--;
}
int finalMinerals = mineralsUpSide + mineralsLeftSide;
int finalToxics = toxicsLeftSide + toxicsUpSide;
for (int x = startX + 1; x < maxBoundx; x++) {
mw = x + mBw;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
}
for (int y = startY + 1; y < maxBoundy - 1; y++) {
mw = maxBoundx - 1 + sidey;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
sidey = sidey + width;
}
finalMinerals += lastMinerals;
finalToxics += toxics;
if (!(finalMinerals / 2.0 < finalToxics) && finalMinerals > maxMinerals) {
maxMinerals = finalMinerals;
}
mBw = mBw - width;
}
}
lineOffset = lineOffset + width;
}
printf("%d\n", maxMinerals);
}
int main() {
char hw[14];
FILE * file = fopen("pub01.in", "r");
char c;
int k = 0;
while ((c = fgetc(file)) != '\n') {
hw[k] = c;
k++;
}
int h, w;
sscanf(hw, "%d %d", &h, &w);
int size = h * w;
int* input = malloc(size * sizeof (int) + 1);
k = 0;
while ((c = fgetc(file)) != EOF) {
if (c == '0' || c == '1' || c == '2') {
input[k] = c - '0';
k++;
}
}
input[k] = '\0';
if (h > w) {
traverseforH(input, h, w);
} else {
traverseforW(input, h, w);
}
return 0;
}
#包括
#包括
国际矿物协会;
void traverseforH(常量整型常量*映射、常量整型高度、常量整型宽度){
常数int h1=高度-1;
常数int w1=宽度-1;
int lineOffset=0;
对于(int startY=0;startYmaxMinerals)){
打破
}
用于(int startX=0;startXmaxMinerals)){
打破
}
int maxBoundl=宽度;
int maxBoundm=宽度;
如果(开始+最大边界-高度-开始>0){
maxBoundl=高度;
maxBoundm=高度;
如果(startX-startY>0){
maxBoundl=maxBoundl+startY-startX;
}否则{
maxBoundm=maxBoundm+startX-startY;
}
}否则如果(开始-开始发送>0){
maxBoundm=maxBoundm+startY-startX;
maxBoundl=maxBoundm;
maxBoundm=maxBoundm+startX-startY;
}否则{
maxBoundl=maxBoundl+startY-startX;
}
int mBw=(maxBoundl-1)*宽度;
int-toxicsLeftSide=0;
int mineralsLeftSide=0;
int-toxicsuppose=0;
int=0;
整数兆瓦;
int=0;
int-toxics=0;
int sidey=线偏移+宽度;
对于(int x=startX;xmaxMinerals){
最大矿物=最新矿物;
}
mBw=mBw-宽度;
国际努弗斯广场;
if(xsidemaxMinerals)){
打破
}
sidey=线偏移+宽度;
lastMinerals=0;
毒物=0;
如果(映射[maxBoundx+lineOffset]==1){
上侧面--;
}else if(映射[maxBoundx+lineOffset]){
毒物;
}
如果(映射[startX+mBw+宽度]==1){
矿质组分--;
}否则,如果(地图[startX+mBw+宽度]){
毒物左侧--;
}
对于(int x=startX+1;x#include <stdio.h>
#include <stdlib.h>
int maxMinerals;
void traverseforH(const int const *map, const int height, const int width) {
const int h1 = height - 1;
const int w1 = width - 1;
int lineOffset = 0;
for (int startY = 0; startY < h1; startY++) {
int yside = height - startY;
if (!(yside * 2 + (yside - 2)*2 > maxMinerals)) {
break;
}
for (int startX = 0; startX < w1; startX++) {
int xside = width - startX;
if (!(xside * 2 + (xside - 2)*2 > maxMinerals)) {
break;
}
int maxBoundl = width;
int maxBoundm = width;
if (startY + maxBoundm - height - startX > 0) {
maxBoundl = height;
maxBoundm = height;
if (startX - startY > 0) {
maxBoundl = maxBoundl + startY - startX;
} else {
maxBoundm = maxBoundm + startX - startY;
}
} else if (startY - startX > 0) {
maxBoundm = maxBoundm + startY - startX;
maxBoundl = maxBoundm;
maxBoundm = maxBoundm + startX - startY;
} else {
maxBoundl = maxBoundl + startY - startX;
}
int mBw = (maxBoundl - 1) * width;
int toxicsLeftSide = 0;
int mineralsLeftSide = 0;
int toxicsUpSide = 0;
int mineralsUpSide = 0;
int mw;
int lastMinerals = 0;
int toxics = 0;
int sidey = lineOffset + width;
for (int x = startX; x < maxBoundm; x++) {
mw = x + lineOffset;
if (map[mw] == 1) {
mineralsUpSide++;
lastMinerals++;
} else if (map[mw]) {
toxicsUpSide++;
toxics++;
}
mw = x + mBw;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
}
for (int y = startY + 1; y < maxBoundl - 1; y++) {
mw = startX + sidey;
if (map[mw] == 1) {
mineralsLeftSide++;
lastMinerals++;
} else if (map[mw]) {
toxicsLeftSide++;
toxics++;
}
mw = maxBoundm - 1 + sidey;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
sidey = sidey + width;
}
if (map[startX + mBw] == 1) {
mineralsLeftSide++;
} else if (map[startX + mBw]) {
toxicsLeftSide++;
}
int upsideData [2];
upsideData[0] = mineralsUpSide;
upsideData[1] = toxicsUpSide;
if (!(lastMinerals / 2.0 < toxics) && lastMinerals > maxMinerals) {
maxMinerals = lastMinerals;
}
mBw = mBw - width;
int noOfSquares;
if (xside < yside) {
noOfSquares = xside - 1;
} else {
noOfSquares = yside - 1;
}
for (int k = 1; k < noOfSquares; k++) {
int maxBoundy = maxBoundl - k;
int maxBoundx = maxBoundm - k;
if (!(((maxBoundx - startX)*2 + (maxBoundx - 2 - startX)*2) > maxMinerals)) {
break;
}
sidey = lineOffset + width;
lastMinerals = 0;
toxics = 0;
if (map[maxBoundx + lineOffset] == 1) {
mineralsUpSide--;
} else if (map[maxBoundx + lineOffset]) {
toxicsUpSide--;
}
if (map[startX + mBw + width] == 1) {
mineralsLeftSide--;
} else if (map[startX + mBw + width]) {
toxicsLeftSide--;
}
for (int x = startX + 1; x < maxBoundx; x++) {
mw = x + mBw;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
}
for (int y = startY + 1; y < maxBoundy - 1; y++) {
mw = maxBoundx - 1 + sidey;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
sidey = sidey + width;
}
int finalMinerals = lastMinerals + mineralsLeftSide + mineralsUpSide;
int finalToxics = toxics + toxicsLeftSide + toxicsUpSide;
if (!(finalMinerals / 2.0 < finalToxics) && finalMinerals > maxMinerals) {
maxMinerals = finalMinerals;
}
mBw = mBw - width;
}
}
lineOffset = lineOffset + width;
}
printf("%d\n", maxMinerals);
}
void traverseforW(int *map, const int height, const int width) {
int h1 = height - 1;
int w1 = width - 1;
int lineOffset = 0;
for (int startY = 0; startY < h1; startY++) {
int yside = height - startY;
if (!(yside * 2 + (yside - 2)*2 > maxMinerals)) {
break;
}
for (int startX = 0; startX < w1; startX++) {
int xside = width - startX;
if (!(xside * 2 + (xside - 2)*2 > maxMinerals)) {
break;
}
int maxBoundl = height;
int maxBoundm = height;
if (startX + maxBoundl - width - startY > 0) {
maxBoundl = width;
maxBoundm = width;
if (startX - startY > 0) {
maxBoundl = maxBoundl + startY - startX;
} else {
maxBoundm = maxBoundm + startX - startY;
}
} else if (startY - startX > 0) {
maxBoundm = maxBoundm + startX - startY;
} else {
maxBoundl = maxBoundl + startX - startY;
maxBoundm = maxBoundl;
maxBoundl = maxBoundl + startY - startX;
}
int mBw = (maxBoundl - 1) * width;
int toxicsLeftSide = 0;
int mineralsLeftSide = 0;
int toxicsUpSide = 0;
int mineralsUpSide = 0;
int mw;
int lastMinerals = 0;
int toxics = 0;
int sidey = lineOffset + width;
for (int x = startX; x < maxBoundm; x++) {
mw = x + lineOffset;
if (map[mw] == 1) {
mineralsUpSide++;
lastMinerals++;
} else if (map[mw]) {
toxicsUpSide++;
toxics++;
}
mw = x + mBw;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
}
for (int y = startY + 1; y < maxBoundl - 1; y++) {
mw = startX + sidey;
if (map[mw] == 1) {
mineralsLeftSide++;
lastMinerals++;
} else if (map[mw]) {
toxicsLeftSide++;
toxics++;
}
mw = maxBoundm - 1 + sidey;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
sidey = sidey + width;
}
if (map[startX + mBw] == 1) {
mineralsLeftSide++;
} else if (map[startX + mBw]) {
toxicsLeftSide++;
}
if (!(lastMinerals / 2.0 < toxics) && lastMinerals > maxMinerals) {
maxMinerals = lastMinerals;
}
mBw = mBw - width;
int noOfSquares;
if (xside < yside) {
noOfSquares = xside - 1;
} else {
noOfSquares = yside - 1;
}
for (int k = 1; k < noOfSquares; k++) {
int maxBoundy = maxBoundl - k;
int maxBoundx = maxBoundm - k;
if (!(((maxBoundx - startX)*2 + (maxBoundx - 2 - startX)*2) > maxMinerals)) {
break;
}
sidey = lineOffset + width;
lastMinerals = 0;
toxics = 0;
if (map[maxBoundx + lineOffset] == 1) {
mineralsUpSide--;
} else if (map[maxBoundx + lineOffset]) {
toxicsUpSide--;
}
if (map[startX + mBw + width] == 1) {
mineralsLeftSide--;
} else if (map[startX + mBw + width]) {
toxicsLeftSide--;
}
int finalMinerals = mineralsUpSide + mineralsLeftSide;
int finalToxics = toxicsLeftSide + toxicsUpSide;
for (int x = startX + 1; x < maxBoundx; x++) {
mw = x + mBw;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
}
for (int y = startY + 1; y < maxBoundy - 1; y++) {
mw = maxBoundx - 1 + sidey;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
sidey = sidey + width;
}
finalMinerals += lastMinerals;
finalToxics += toxics;
if (!(finalMinerals / 2.0 < finalToxics) && finalMinerals > maxMinerals) {
maxMinerals = finalMinerals;
}
mBw = mBw - width;
}
}
lineOffset = lineOffset + width;
}
printf("%d\n", maxMinerals);
}
int main() {
char hw[14];
FILE * file = fopen("pub01.in", "r");
char c;
int k = 0;
while ((c = fgetc(file)) != '\n') {
hw[k] = c;
k++;
}
int h, w;
sscanf(hw, "%d %d", &h, &w);
int size = h * w;
int* input = malloc(size * sizeof (int) + 1);
k = 0;
while ((c = fgetc(file)) != EOF) {
if (c == '0' || c == '1' || c == '2') {
input[k] = c - '0';
k++;
}
}
input[k] = '\0';
if (h > w) {
traverseforH(input, h, w);
} else {
traverseforW(input, h, w);
}
return 0;
}
#include<stdio.h>
int min(int a,int b){
return (a<=b)?a:b;
}
int max(int a,int b){
return (a>=b)?a:b;
}
// currently hard-coding dimensions for test purposes
// horizontal sums
int rowSumFor1[600][600];
int rowSumFor2[600][600];
// vertical sums
int colSumFor1[600][600];
int colSumFor2[600][600];
int main(){
int w,h;
scanf("%d %d",&h,&w);
for(int row=1;row <= h;row++)for(int col=1;col <= w;col++){
int temp;
scanf("%d",&temp);
// first add previous sum
rowSumFor1[row][col]=rowSumFor1[row][col - 1];
rowSumFor2[row][col]=rowSumFor2[row][col - 1];
colSumFor1[col][row]=colSumFor1[col][row - 1];
colSumFor2[col][row]=colSumFor2[col][row - 1];
if(temp==1){
rowSumFor1[row][col]++;
colSumFor1[col][row]++;
}
else if(temp==2){
rowSumFor2[row][col]++;
colSumFor2[col][row]++;
}
else{
// do nothing
}
}
int result = 0,rowId,colId,mlength;
for(int len=min(w,h); len > 1 ; len-- ) // iteration on possible lengths
{
for(int row=1;row <= (h - len + 1);row++)for(int col=1;col <= (w - len + 1);col++){ // iteration on all co-ordinates as upper-left corner of our square
// Do calculation here for properties and necessary checking constraints for validity of this square
// Note: not checking trivial conditions like boundary conditions in square, you will have to!!
// Beware of over-counting of corners here, one way to avoid is to select indices such that they don't overcount corners
// 4x4 square example for counting
// aaab
// d b
// d b
// dccc
int topEdge1 = rowSumFor1[row][col + len - 2] - rowSumFor1[row][col - 1];
int bottomEdge1 = rowSumFor1[row + len - 1][col + len - 1] - rowSumFor1[row + len - 1][col];
int leftEdge1 = colSumFor1[col][row + len - 1] - colSumFor1[col][row];
int rightEdge1 = colSumFor1[col + len - 1][row + len - 2] - colSumFor1[col + len - 1][row - 1];
int ones= topEdge1 + bottomEdge1 + leftEdge1 + rightEdge1; // # of 1s on perimeter of this square
int topEdge2 = rowSumFor2[row][col + len - 2] - rowSumFor2[row][col-1];
int bottomEdge2 = rowSumFor2[row+len-1][col+len-1] - rowSumFor2[row+len-1][col];
int leftEdge2 = colSumFor2[col][row + len - 1] - colSumFor2[col][row];
int rightEdge2 = colSumFor2[col + len - 1][row + len - 2] - colSumFor2[col + len -1][row - 1];
int twos= topEdge2 + bottomEdge2 + leftEdge2 + rightEdge2; // # of 2s on perimeter of this square
if(ones >= 2* twos){
if(ones > result){
result = ones;
rowId = row;
colId = col;
mlength = len;
}
}
}
}
printf("%d %d %d\n",rowId,colId,mlength);
printf("%d\n",result);
return 0;
}