【PAT乙级】1068 万绿丛中一点红

题目链接:1068 万绿丛中一点红

思路

通过这道题学到了map的使用,大佬们笑我的时候小声点。

  1. 写在前方:
    1. 开始时候没注意到不能重复这个条件,网上看大佬们的代码。这才发现大家都在用map记录点出现的次数。然后还有个有趣的事是大家都用二维数组存八个方向的坐标偏移,就我用双重循环来遍历,不过我感觉要是数据量大还是我叼些,这题就八个点还是大佬叼,开拓了我的思路是真的,看别人代码受益匪浅。
  2. 代码过程:
    1. 输入数据时记录数据出现次数。
    2. 判别数据时跳过重复点。
    3. 发现符合要求则记录该点坐标,计数加一。
    4. 如果计数达到2,输出多点结果并结束程序。
    5. 最终统计0或1,分别处理。
  3. 注意点:
    1. 他这里的坐标格式时<列,行>,我因为写反了所以把开头的M,N对调了。
    2. 数值差是绝对值。
    3. 边界也是要判定的,我用了愚蠢的扩大一圈0的策略。
  4. 可优化点:
    1. 判别时其实有个可以再优化的地方就是当你发现两方之差小于阈值,这其实不仅排除了本点,也可以同时排除那个点,一次排除多点提升效率。

代码

#include <iostream>
#include <map>
using namespace std;

int a[1002][1002] = {0};
map<int, int> mp;

int distinct(int i,int j,int TOL){
    for(int k=-1;k<2;k++){
        for(int l=-1;l<2;l++){
            if(k==0 && l==0) continue;//不与本身比较
            //差的绝对值不符合要求
            if(a[i][j]-a[i+k][j+l]<=TOL&&a[i][j]-a[i+k][j+l]>=-TOL) return 0;
        }
    }
    return 1;
}

int main(){
    int M, N, TOL, x = 0, y = 0, count = 0;
    cin >> N >> M >> TOL;//行列写反了,该这里最简单了。。。
    for(int i=1;i<M+1;i++){
        for(int j=1;j<N+1;j++){
            scanf("%d",&a[i][j]);
            mp[a[i][j]]++;
        }
    }
    
    for(int i=1;i<M+1;i++){
        for(int j=1;j<N+1;j++){
            if(mp[a[i][j]]>1)continue;//跳过重复点
            if(distinct(i,j,TOL)){
                count++;
                x = i;
                y = j;
                if(count == 2){//多于一个点输出结果
                    printf("Not Unique\n");
                    return 0;
                }
            }
        }
    }
    if(!count) printf("Not Exist\n");
    else printf("(%d, %d): %d\n",y,x,a[x][y]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wulingyu501/article/details/108998202