201:Squares

45 篇文章 0 订阅
14 篇文章 0 订阅

Squares


version 1(20ms):

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 10;
int n,m,c,H[maxn][maxn],V[maxn][maxn];
char readchar(){
    for(;;){
        c = getchar();
        if(c != '\n' && c != '\r') return c;
    }
}
int countsq(int len){
    int cnt = 0;
    for(int i = 1;i+len <= n;i++){
        for(int j = 1;j+len <= n;j++){
            int mark = 1;
            for(int k = 0;mark && k <= len - 1;k++){
                if(!H[i][j+k] || !V[i+k][j]) mark = 0;//从左上角的点分别往右边和下边看
                if(!H[i+len][j+k]) mark = 0;//从左下角的点往右边看
                if(!V[i+k][j+len]) mark = 0;//从右上角的点往下边看
            }
            if(mark) cnt++;
        }
    }
    return cnt;
}
int main(){
    int kase = 0;
    while(scanf("%d%d",&n,&m) == 2){
        memset(H,0,sizeof(H));
        memset(V,0,sizeof(V));
        int a,b;
        while(m--){
            c = readchar();
            scanf("%d %d",&a,&b);
            if(c == 'H') H[a][b]= 1;
            if(c == 'V') V[b][a]= 1;//这个地方注意书上说的是不对的 是 b a
        }
        if(++kase > 1) printf("\n**********************************\n\n");
        printf("Problem #%d\n\n",kase);
        int mark = 0;
        for(int i = 1;i <= n;i++){
            a = countsq(i);
            if(a){
                mark = 1;
                printf("%d square (s) of size %d\n",a,i);
            }
        }
        if(!mark) printf("No completed squares can be found.\n");
    }
    return 0;
}

又想了下,如果以某点为左上顶点不存在较短的正方形,那么也应该不存在更大的正方形,所以可以把这些点存储一下,以后根本不用去检查。

version 2:

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 10;
int n,m,c,H[maxn][maxn],V[maxn][maxn],record[maxn][maxn];
char readchar(){
    for(;;){
        c = getchar();
        if(c != '\n' && c != '\r') return c;
    }
}
int countsq(int len){
    int cnt = 0;
    for(int i = 1;i+len <= n;i++){
        for(int j = 1;j+len <= n;j++){
            if(record[i][j]) continue;
            int mark = 1;
            for(int k = 0;mark && k <= len - 1;k++){
                if(!H[i][j+k] || !V[i+k][j]) mark = 0;//从左上角的点分别往右边和下边看
                if(!H[i+len][j+k]) mark = 0;//从左下角的点往右边看
                if(!V[i+k][j+len]) mark = 0;//从右上角的点往下边看
            }
            if(mark) cnt++;
            else record[i][j] = 1;
        }
    }
    return cnt;
}
int main(){
    int kase = 0;
    while(scanf("%d%d",&n,&m) == 2){
        memset(H,0,sizeof(H));
        memset(V,0,sizeof(V));
        memset(record,0,sizeof(record));
        int a,b;
        while(m--){
            c = readchar();
            scanf("%d %d",&a,&b);
            if(c == 'H') H[a][b]= 1;
            if(c == 'V') V[b][a]= 1;
        }
        if(++kase > 1) printf("\n**********************************\n\n");
        printf("Problem #%d\n\n",kase);
        int mark = 0;
        for(int i = 1;i <= n;i++){
            a = countsq(i);
            if(a){
                mark = 1;
                printf("%d square (s) of size %d\n",a,i);
            }
        }
        if(!mark) printf("No completed squares can be found.\n");
    }
    return 0;
}

但是 WA 了。。。仔细一想其实不对,如下图:


虽然这个点不存在边长为1的正方形,但是有边长为2的正方形,所以上面减少时间复杂度的做法行不通。但是如果这点的右边和下边这条线断掉的话,肯定不存在更大的正方形,以后是不需要检查的。

version 3(30ms):

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 10;
int n,m,c,H[maxn][maxn],V[maxn][maxn],record[maxn][maxn];
char readchar(){
    for(;;){
        c = getchar();
        if(c != '\n' && c != '\r') return c;
    }
}
int countsq(int len){
    int cnt = 0;
    for(int i = 1;i+len <= n;i++){
        for(int j = 1;j+len <= n;j++){
            if(record[i][j]) continue;
            int mark = 1,mark2 = 0;
            for(int k = 0;mark && k <= len - 1;k++){
                if(!H[i][j+k] || !V[i+k][j]) {mark = 0,mark2 = 1;}//从左上角的点分别往右边和下边看
                if(!H[i+len][j+k]) mark = 0;//从左下角的点往右边看
                if(!V[i+k][j+len]) mark = 0;//从右上角的点往下边看
            }
            if(mark) cnt++;
            if(mark2) record[i][j] = 1;
        }
    }
    return cnt;
}
int main(){
    int kase = 0;
    while(scanf("%d%d",&n,&m) == 2){
        memset(H,0,sizeof(H));
        memset(V,0,sizeof(V));
        memset(record,0,sizeof(record));
        int a,b;
        while(m--){
            c = readchar();
            scanf("%d %d",&a,&b);
            if(c == 'H') H[a][b]= 1;
            if(c == 'V') V[b][a]= 1;
        }
        if(++kase > 1) printf("\n**********************************\n\n");
        printf("Problem #%d\n\n",kase);
        int mark = 0;
        for(int i = 1;i <= n;i++){
            a = countsq(i);
            if(a){
                mark = 1;
                printf("%d square (s) of size %d\n",a,i);
            }
        }
        if(!mark) printf("No completed squares can be found.\n");
    }
    return 0;
}

这次总算AC了,但是没想到时间竟然是30ms,可能减少的时间还没有增加两个判断语句增加的时间多。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值