杭电复试2015笔试题解答

/*给定一个字符串,计算字符串中数值的个数并求和。其中还包含了负号,若
紧跟负号的是一个数值,则表示这是一个负数,若后面跟着的不是数字,则不表
示什么。
输入:一个字符串
输出:数值个数 数值和
列子
输入:312ab-2-- -9–a
输出:3 301
*/

//与2010年的试题2类似字符串中提取数字并求和 
//可以选择把一个数先整体存到数组中,在转化为数,str2int 
//此题主要是负号的判别,可以通过标志位实现,另外注意在字符判断时把负号剔除。 
#include<cstdio>
#include<iostream> 
#include<string>
#include<string.h> 
using namespace std;

int main(){
	string str;
	char tempnum[110];//里面暂时存储一个数据 
	int geshu=0;//有多少个数值 
	int sum=0;//数值和 
	bool flag=true;//‘-’负号的标志位 ,false表示负号 
	getline(cin,str);//输入带空格的一行字符串
	int length=str.size();
	for(int i=0;i<length;){
		if(str[i]=='-'){//如果是负号 
			flag=false;
//			printf("%d\n",flag);
			i++;
	//		continue;//下面的程序不执行,节省时间 
		}else if('0'<=str[i] && str[i]<='9'){//是数字,将其整个存储到数组中,然后在计算 
			int temp=0; //
			while('0'<=str[i] && str[i]<='9'){
				temp=temp*10+str[i]-'0';
				i++;
			}
	//		printf("%d\n",temp); 
			geshu++;
		//	printf("%d\n",flag);
			if(flag==true){
				sum=sum+temp; 
			}else{
				sum=sum-temp;
			} 
			printf("%d\n",sum);
			flag=true;//重新置为正数,如果遇到负数才置为负数 
		} else{//不是负号也不是数字 
			flag=true;//负号后面没有紧跟数字,那么这个负号就无效 
			while(str[i]>'9' || str[i]<'0' ){//字符型有可能吧'-'统计上去 
				if(str[i]=='-') break; 
				i++;//走链
			} 
		}
	} 
	printf("%d %d\n",geshu,sum); 
	return 0;
} 

/*.给定一个数字矩阵,如果上下左右数值相同,则表示是一个连通的区域。
求矩阵中连通块的数量。
输入:
先是矩阵的行数和列数
接着是矩阵
输出:
连通块的数量
列子:
5 6
4 4 4 4 4 4
4 2 3 3 1 4
4 2 2 3 1 4
4 2 3 3 1 4
4 4 4 4 4 4
输出:
4
*/
//BFS,DFS,并查集应该都可以

#include<cstdio>
#include<queue>
using namespace std;
const int maxn=110;

struct node{
	int x,y;
}Node;//位置节点,写成一个结构体 

int matrix[maxn][maxn];
bool inq[maxn][maxn]={false};//标记数组,记录某一位置是否入过队 
int n,m;//n行m列
int X[4]={0,0,1,-1};//增量数组,因为BFS访问时是上下左右一圈相邻的都得访问 
int Y[4]={1,-1,0,0}; //设置数组后就可以用for循环来实现,避免枚举四次位置 
 
//用BFS遍历 
/*枚举每个位置的数先记录当前的数,然后用BFS遍历与该位置相邻的四个位置,判断他们是否与之相等,若想等
则同样去查询相邻的位置并将其做标记,以免走回头路,所以这里的标记数组是二维的,表示某一位置是否被访问过
*/
bool judge(int x,int y,int value){//判断这个位置是否可以访问 
	if(x<0 || x>=n || y<0 ||y>=m){//越界 
		return false;
	}
	if(matrix[x][y]!=value || inq[x][y]==true) return false;//已经访问过的顶点或者不是一个数值的不在访问
	return true; 
} 
//BFS函数访问(x,y)所在的位置快等于value的元素,将该块所有元素inq置为true 
void BFS(int x,int y,int value){
	queue<node> Q;//定义队列 
	Node.x=x;
	Node.y=y;
//	int temp=matrix[x][y];
	Q.push(Node);//起始位置节点入队
//	inq[x][y]=true;//在入队时就将元素做访问标记,避免重复入队
	while(!Q.empty()){
		node top=Q.front();//取出队头元素
		inq[top.x][top.y]=true; 
		Q.pop();//队头元素出队
//		printf("x=%d,y=%d ",top.x,top.y);//测试所加 
		for(int i=0;i<4;i++){
			int newx=top.x+X[i];//设置newx可以保留top.x中的值 
			int newy=top.y+Y[i]; 
			if(judge(newx,newy,value)){//如果这个位置可以访问 
				Node.x=newx,Node.y=newy;//
				Q.push(Node);//节点入队 
				inq[newx][newy]=true; 
			} 
		} 
	} 
}
//DFS将同一个连通块中的元素做标记 
void DFS(int x,int y,int value){
	//递归边界 
	if(x<0 || x>=n || y<0 ||y>=m){//越界返回 
		return;
	}
	if(matrix[x][y]!=value || inq[x][y]==true) return;////已经访问过的顶点或者不是一个数值,递归边界返回
	for(int i=0;i<4;i++){//往四个方向递归 
		inq[x][y]=true;//做访问标记 
		DFS(x+X[i],y+Y[i],value);
	} 
	 
} 
 
int main(){
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			scanf("%d",&matrix[i][j]);
		}
	}
	
	int ans=0;//存储连通块数
	for(int x=0;x<n;x++){
		for(int y=0;y<m;y++){//枚举每一个位置 
		//如果元素未入过队	
			if(inq[x][y]==false){
				int value=matrix[x][y];
				ans++;
				//BFS(x,y,value);//将matrix矩阵中的同一连通快全部访问并做标记
				DFS(x,y,value); 
			} 
		}
	} 
	printf("%d\n",ans); 
	return 0;
} 
发布了23 篇原创文章 · 获赞 62 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_42264284/article/details/105613174