北大ACM(1009Edge Detection)代码

/*
	Memory 172K Time 16MS
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/*
	对于图像进行边缘检测编码。简单边缘检测算法规则如下
		输出像素值设置为它与输入图像中所有周围像素之间的差的最大绝对值。 如下:
		15  15  15  15  100 100 100
		100 100 100 100 100 100 100
		100 100 100 100 100 25  25
		175 175 25  25  25  25  25
		175 175 25  25  25  25  25

		输出如下
		85  85  85  85  85  0  0 
		85  85  85  85  85  75 75 
		75  75  75  75  75  75 75
		75  150 150 75  75  75 0
		0   150 150 0   0   0  0  
*/
/*		先需要编写一个程序 利用行程编码(RLE) 对所有图像进行编码 
		程序输入格式如下
*/
	///	 w		表示像素值的宽度 也就是每一列的长度
	///	 a b	表示RLE 对  存在像素值 a的b个对象
	///  0 0	表示输入结束
	///	 0		表示没有数据需要处理 循环结束		


#define SIZE 1010			//表示输入图像数据的对数大小


struct Pixel
{
	int value;			//表示数据值
	int pos;			//数据值所在图像的位置
}outData[SIZE * 9];

int width;				//图像宽度
int inNum, outNum;		//输入数据的数量和输出数据的数量
int total;				//数据的总长度

int inData[SIZE][2];	//下标[i][0]表示数据值 下标[i][1]表示的是数值所在的位置

int cmp(const void* lhs, const void * rhs);			//比较两个Pixel结构的下标然后进行排序
int getVal(int pos);								//获取该位置上的数据
int cal(int pos);									//获取该位置的值与周围数值的最大差值
void solve();										//调用其他函数来进行排序并打印


int main()
{
	int i, j;
	
	while (scanf_s("%d", &width) && width)			//持续录入数据
	{
		total = 0;
		i = 0;
		printf_s("%d\n", width);
		while (scanf_s("%d %d", &inData[i][0], &inData[i][1]))	//录入单对数据
		{
			j = inData[i][1];				//记录该数据长度
			inData[i][1] = total;			//将数据长度改为数据开始位置
			total += j;						//数据总长度每次加上单对数据长度
			if (j == 0) break;				//数据长度为0 结束录入
			++i;
		}
		///记录输入数量
		inNum = i;
		///录入数据进行处理
		solve();
	}

	printf_s("0\n");
	return 0;
}

int cmp(const void * lhs, const void * rhs)
{
	return ((struct Pixel*)lhs)->pos -  ((struct Pixel*)rhs)->pos;
}

int getVal(int pos)
{
	int low = 0, high = inNum - 1;			
	int mid;

	///使用二分查找法来进行查找传递的pos位于图像数据中的哪一个位置上
	while (low <= high)
	{
		mid = (low + high) / 2;

		if (inData[mid][1] > pos)		//当前位置大于查找位置时,表示需要向前查找
			high = mid - 1;
		else
			low = mid + 1;			//否则表示需要向后查找
	}
	return inData[high][0];
}

int cal(int pos)			//返回该位置的数据与周围数据的最大差值
{
	int ret = 0;	//返回值
	int row, col;	//行与列
	int p;			//周围元素坐标
	int i, j;
	int value;		//单次的差值
	int tmp_value = getVal(pos);		//获取当前位置的数据,避免重复调用

	row = pos / width;
	col = pos % width;

	对于赋值的条件来说,避免不必要的循环。当处于第一行时  无需要去比较上一行的元素 ,当处于最后一行时 无需要去比较下一行的元素
	for(i =row -1; i < row + 2; ++i)
		for (j =col -1; j < col+2; ++j)	//列也是一样的 处于第一列和最后一列时无需要去比较不存在的列
		{
			p = i * width + j;

			if (i < 0 || j < 0 || j >= width || p >= total || p == pos) 
				continue;

			value = abs(getVal(p) - tmp_value);
			if (value > ret)
				ret = value;
		}

	return ret;
}

void solve()
{
	int i, j, k;
	int pos;
	int row, col;
	struct Pixel cur;			//用于打印时计算数值的数量

	outNum = 0;

	for (i = 0; i <= inNum; ++i)
	{
		row = inData[i][1] / width;
		col = inData[i][1] % width;

		///通过循环来遍历每个数据值,并计算出该数据值与周围数据的差值,然后添加到结构中
		for(j = row - 1; j < row + 2; ++j)
			for (k = col - 1; k < col + 2; ++k)
			{
				pos = j * width + k;

				if (j < 0 || pos < 0 || pos >= total)
					continue;

				outData[outNum].value = cal(pos);
				outData[outNum].pos = pos;
				++outNum;
			}
	}
	///对结构进行排序
	qsort(outData, outNum, sizeof(struct Pixel), cmp);
	cur = outData[0];

	//进行打印
	for (i = 0; i < outNum; ++i)
	{
		if (cur.value == outData[i].value)			//如果数据值相同的话,不进行显示,直接循环下一个。
			continue;
		printf_s("%d %d\n", cur.value, outData[i].pos - cur.pos);	//直到存在不同的数据值的时候进行显示,显示该数据值和数据值的数量
		cur = outData[i];
	}
	printf("%d %d\n", cur.value, total - cur.pos);		//最后还需要打印出最后一个的值
	printf_s("0 0\n");
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

David_TD

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值