[编程题]特征提取

本文介绍了一位算法工程师如何从猫咪的视频中提取运动信息。通过识别连续出现的猫咪特征,小明寻找最长的特征运动。他利用map数据结构存储和检测连续性,实现了对视频帧中猫咪运动的高效分析。最终,通过对每一帧的特征进行处理,找到了最长的特征运动并输出其长度。
摘要由CSDN通过智能技术生成

小明是一名算法工程师,同时也是一名铲屎官。某天,他突发奇想,想从猫咪的视频里挖掘一些猫咪的运动信息。为了提取运动信息,他需要从视频的每一帧提取“猫咪特征”。一个猫咪特征是一个两维的vector<x, y>。如果x_1=x_2 and y_1=y_2,那么这俩是同一个特征。

因此,如果喵咪特征连续一致,可以认为喵咪在运动。也就是说,如果特征<a, b>在持续帧里出现,那么它将构成特征运动。比如,特征<a, b>在第2/3/4/7/8帧出现,那么该特征将形成两个特征运动2-3-4 和7-8。

现在,给定每一帧的特征,特征的数量可能不一样。小明期望能找到最长的特征运动。

输入描述:

第一行包含一个正整数N,代表测试用例的个数。

每个测试用例的第一行包含一个正整数M,代表视频的帧数。

接下来的M行,每行代表一帧。其中,第一个数字是该帧的特征个数,接下来的数字是在特征的取值;
比如样例输入第三行里,2代表该帧有两个猫咪特征,<11><22>
所有用例的输入特征总数和<100000

N满足1≤N≤100000,M满足1≤M≤10000,一帧的特征个数满足 ≤ 10000。
特征取值均为非负整数。

输出描述:

对每一个测试用例,输出特征运动的长度作为一行

示例:

输入
1
8
2 1 1 2 2
2 1 1 1 4
2 1 1 2 2
2 2 2 1 4
0
0
1 1 1
1 1 1
输出
3
说明
特征<1,1>在连续的帧中连续出现3次,相比其他特征连续出现的次数大,所以输出3

解析:
先看我们要存储的数据结构:一个二维坐标<x,y>,以及一个表示连续次数的整型。

显然一开始可能会使用二维数组,但当我们要检测连续性时,我们就需要变量整个二维数组(即便里面有些数据为0),显然,这里无法使用二维数组来满足我们的需求。

因此这里使用的是map类,map类能提供一个键值(key)以及一个值值(value)。

因此我们可以用一个map类对象(pair<x,y>)表示坐标<x,y>。

显然我们仍然缺少表达连续次数的整型,于是我们可以再建立一个map类,用于存放坐标以及连续次数(map<pair<x,y>,int>),这样就可以解决数据存取问题。

然后是如何检测连续性问题。

由于存在清零操作(在连续断开时需要重新计数),因此我们需要两张map,一张记录当前读取的,一张记录连续性。

代码实现:

#include <iostream>
#include <map>     //调用map类
using namespace std;

int main()
{
	int n, m;//测试次数及帧数
	cin >> n;

	int len;          //每帧动作数
	pair<int, int> xy;//坐标

	while (n--)
	{
		cin >> m;

		int max = 0;                 //最大连续次数
		map<pair<int, int>, int> pre;//记录连续次数
		map<pair<int, int>, int> now;//记录当前帧数次数

		while (m--)
		{
			cin >> len;//动作数

			for(int i=0;i<len;i++)
			{
				//读入坐标
				cin >> xy.first >> xy.second;

				//map.count用于返回键对应的元素的次数(map中键值唯一)
				//若存在,则当前表now该元素连续出现的次数是连续表pre的次数+1
				if(pre.count(xy))
				{
					now[xy] = pre[xy] + 1;
				}
				//否则,则表示该元素是头次出现或已断开连续
				else
				{
					now[xy] = 1;
				}

				//当前元素连续出现次数与最大连续出现次数比较
				if(now[xy]>max)
				{
					max = now[xy];
				}
			}

			//连续表pre清零,now表现在的是现仍连续的元素,与pre交换,作为下一帧的连续表
			pre.clear();
			pre.swap(now);
		}
		cout << max<<endl;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值