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