编程练习20180909

1.找出一个字符串中无重复字符的最长子字符串的长度

如"abcabcbb"的最长无重复的子串有:"abc","bca","acb",最长的无重复字符的字串的长度为3;

abca

abcb

abcc

思路:

如string str="abcb"

建立一个存储找到的所以没有重复字母的子串的向量:

vector<int> MaxSubStrVec ;//将每一次找到的无重复字母的字串的长度都push_back进去,最后输出起最大值。或者直接用个优先队列,大顶堆来保存:priority_queue;

建立一个标记向量,标记26个字母在字串中的出现与否的状态:

vector<int> Flags(26,0);//初始全为0

再建立一个子串字符(字母)出现在主串中的位置(下标)向量:

vector<int> Loc(26,0);//初始全为0

i=0;str[0]=a;if(Flags[str[0]-'a']==0){Flags[str[0]-'a']=1;maxLength++;   Loc[str[i]-'a']=i}

i=0;str[1]=b;if(Flags[str[1]-'a']==0){Flags[str[1]-'a']=1;maxLength++;Loc[str[i]-'a']=i}

i=2;str[2]=c;if(Flags[str[2]-'a']==0){Flags[str[2]-'a']=1;maxLength++;Loc[str[i]-'a']=i}

i=3;str[3]=b;Flags[str[3]-'a']!=0,,则不在纳入子串,请将下标i回溯道前面子串重复的字符的下一个位置2,Flags清0,Loc清0

对于abcd这样主串就没有重复字符的,也要将最大值累加上去。

2.标记矩阵的连通分量(数字图像处理连通域标记问题)

5
1 0 0 1 1
1 0 0 1 1
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
3
1 0 0 2 2
1 0 0 2 2
0 0 3 0 0
0 0 3 0 0
0 0 3 0 0

如下面的矩阵,有三个连通域(连通只四邻域连通,即上下左右的值相同的判为连通)

1 0 0 1 1
1 0 0 1 1
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0

有三个连通域,标记如下:

1 0 0 2 2
1 0 0 2 2
0 0 3 0 0
0 0 3 0 0
0 0 3 0 0

思路:利用栈,区域生长,直到长到无法扩充该区域的时候,开始退栈!

实现代码:

#include "stdafx.h"

#include<iostream>
#include<vector>
#include<stack>

using namespace std;



typedef struct Point{
	int x, y;
}Point;


void MarkMatrix(int i, int j, vector<vector<int>>& Matrix, vector<vector<int>>& Visited, vector<vector<int>>& Flags, int DepartmentCount)
{
	if (Matrix[i][j] == 1 && Visited[i][j] == 0 )
	{
		Visited[i][j] = 1;
		if (i - 1 >= 0)
		{
			MarkMatrix(i-1, j,  Matrix,  Visited,  Flags,  DepartmentCount);
		}
		if (i + 1 < Matrix.size())
		{
			MarkMatrix(i + 1, j, Matrix, Visited, Flags, DepartmentCount);
		}
		if (j - 1 >= 0)
		{
			MarkMatrix(i, j-1, Matrix, Visited, Flags, DepartmentCount);
		}
		if (j + 1 <Matrix.size())
		{
			MarkMatrix(i, j + 1, Matrix, Visited, Flags, DepartmentCount);
		}
		
		Flags[i][j] = DepartmentCount;
	}

}

int HowManyDepatment(vector<vector<int>>& Matrix, vector<vector<int>>& Visited, vector<vector<int>>& Flags)
{
	int M = Matrix.size();
	int DepartmentCount = 0;
	for (int i = 0; i < M; i++)
	{
		for (int j = 0; j < M; j++)
		{
			if (Matrix[i][j] == 1 && Visited[i][j] == 0)
			{
				DepartmentCount++;
				MarkMatrix(i, j, Matrix, Visited, Flags, DepartmentCount);
			}			
		}
	}
	return DepartmentCount;
}



int main(int argc, char* argv[])
{
	int M;
	cin >> M;
	vector<vector<int>> Matrix, Visited, Flags;
	int flag;
	for (int i = 0; i < M; i++)
	{
		vector<int> matrixRow,visitedRow,flagsRow;
		for (int j = 0; j < M; j++)
		{
			cin >> flag;
			matrixRow.push_back(flag);
			visitedRow.push_back(0);
			flagsRow.push_back(0);
		}
		Matrix.push_back(matrixRow);
		Visited.push_back(visitedRow);
		Flags.push_back(flagsRow);
	}


	//int count = 0;
	//for (int i = 0; i < M; i++)
	//{
	//	for (int j = 0; j < M; j++)
	//	{
	//		bool flag1 = false;
	//		bool flag2 = false;
	//		if (Matrix[i][j] == 1)
	//		{
	//			if (i - 1 >= 0)
	//			{
	//				if (Matrix[i - 1][j] == 1)
	//				{
	//					flag1 = true;
	//				}
	//				else
	//				{
	//					flag1 = false;
	//				}
	//			}
	//			if (j - 1 >= 0)
	//			{
	//				if (Matrix[i][j - 1] == 1)
	//				{
	//					flag2 = true;
	//				}
	//				else
	//				{
	//					flag2 = false;
	//				}
	//			}
	//			if (!flag1&&!flag2)
	//			{
	//				count++;
	//			}
	//		}
	//	}
	//}

	//stack<Point> CC;
	//for (int i = 0; i < M; i++)
	//{
	//	for (int j = 0; j < M; j++)
	//	{
	//		if (Visited[i][j] == 0 && Matrix[i][j] == 1)
	//		{
	//			Visited[i][j] = 1;
	//			Point p1, p2, p3, p4;
	//			if (i - 1 >= 0)
	//			{
	//				if (Visited[i - 1][j] == 0 && Matrix[i - 1][j] == 1)
	//				{
	//					p1 = { i - 1, j };//上
	//					CC.push(p1);
	//				}
	//				
	//			}
	//			if (j - 1 >= 0)
	//			{
	//				if (Visited[i][j - 1] == 0 && Matrix[i][j - 1] == 1)
	//				{
	//					p2 = { i, j - 1 };//左
	//					CC.push(p1);
	//				}
	//			
	//			}
	//			if (i + 1 < M)
	//			{
	//				p3 = { i + 1, j };//下
	//			}
	//			if (j + 1 < M)
	//			{
	//				p4 = { i, j + 1 };//右
	//			}
	//		}
	//	}
	//}



	cout << HowManyDepatment(Matrix, Visited, Flags);

	cout << endl;
	for (int i = 0; i < M; i++)
	{
		for (int j = 0; j < M; j++)
		{
			cout << Flags[i][j] << " ";
		}
		cout << endl;
	}
	cout << endl;

	system("pause");

	return 0;
}

/*

5
1 0 0 1 1
1 0 0 1 1
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0



5
1 0 0 1 1
1 0 0 1 1
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
3
1 0 0 2 2
1 0 0 2 2
0 0 3 0 0
0 0 3 0 0
0 0 3 0 0

请按任意键继续. . .
*/

3.IP地址忘记输入.分隔号了,给定一IP,求合理的还原IP数目

如本来是10.0.0.1的IP

今是10001

还原出所有可能的原始IP,输出所有可能的原始IP数量

8888就只能还原为8.8.8.8

255255255也只能还原为255.255.255.255

4.关系图:找红人

用户数N

有M个关系对(A,B):表示A关注了B

关注具有传递性:A关注了B,B关注了C,我们认为A间接也关注了C

如果一个用户被N个用户直接或间接关注,那么认为该用户是网红,

求网红的个数?

输入:

3

3

1 2 2 1 2 3

N=3

M=3

(1,2) (2,1) (2,3)

1->2

2->1

2->3

(有环的真是奇葩!)

这样解释:1和2互粉,那么认为1和2都有两个粉丝,自己是自己的粉丝

1有一个关注者

1->2->3

2->3

那么3就有3个粉丝,3号就是网红!

编程题

猜你喜欢

转载自blog.csdn.net/m0_37357063/article/details/82562554
今日推荐