杭电2015复试上机真题

ps:题是别的地方copy过来的,代码是自己的

第一题:

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

#include<stdio.h>
#include<stdlib.h>

int main(){
	char a[100];
	while(scanf("%s",a) != EOF){
		int numcount = 0; //输出用,数字个数 
		int sum = 0;      //输出用,和 
		
		char num[50];  //记录数字。转换成int型 
		int len = 0;   //记录数组长度 
		int sym = 1;   //记录该数字符号 
		
		char* p = a;
		while(*p != '\0'){ 
			if(*p >= '0' && *p <= '9'){
				num[len++] = *p;
			}
 			else{			//不是数字时,先输出数字,后判断'-' 
				if(len != 0){
					num[len] = '\0';
					sum += (atoi(num) * sym);					
					len = 0;    
					sym = 1;   //每次累加之后sym归1 
					numcount++;  
				}
				if(*p == '-' && *(p + 1) >= '0' && *(p + 1) <= '9'){      //看到-符号且下一位为数字,sym就变成 -1 
					sym = -1;
				}
			}
			p++;
		}
		if(len){
			num[len] = '\0';
			sum += (atoi(num) * sym);
			numcount++;  	
		}
		printf("%d %d\n",numcount,sum);
	}
	return 0;
}

第二题:

给定一个数字矩阵,如果上下左右数值相同,则表示是一个连通的区域。求矩阵中连通块的数量。

第一行为矩阵m行n列,然后输入矩阵元素。

输入:

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 

输出 

/*
    连通块问题可以想象这是个有颜色的棋盘,如果只有与一个区域染成了白色,那么连通块数量为1(可以认为成自成一连通块)
    如果此时白色左边染黑,同理,连通块数量为2。
    如果黑色下边染黑,那么连通块数量为2,因为新增的黑块与原来的黑块连成了新的一个整体的连通块,数量不变,同理不染黑染白则返回3
    因为新的白色在四个方向上并没有与第一个白块相邻(有些题判断八个方向时,是连通的)
    很明显,原题的输入中1,2,3,4都为连通,且连通块各只有1一个
*/
#include<cstdio>
#include<cstdlib>
#include<stack>
//深度搜索典型题,用栈实现,非递归 
using namespace std;

int MAX_M;
int MAX_N;

void DFS(int** a,int** b,int m,int n){	
	int f = a[m][n];
	stack<int> s;   //创建int型的栈,化二维坐标为一位整形 r = m * MAX_M + n 
	s.push(m * MAX_M + n);	
	
	do{
		int x = s.top() / MAX_N;   //转换为二维坐标 
		int y = s.top() % MAX_N; 
		b[x][y] = 1;
		s.pop(); 
		if(y > 0 && b[x][y - 1] == 0 && a[x][y - 1] == f){   				//左块进栈 满足条件不为边界且未被访问且值相等 
			s.push(x * MAX_N + y - 1);
		} 
		if(y < MAX_N - 1 && b[x][y + 1] == 0 && a[x][y + 1] == f){			//右块进栈 
			s.push(x * MAX_N + y + 1);
		} 
		if(x > 0 && b[x - 1][y] == 0 && a[x - 1][y] == f){					//上块进栈 
			s.push(MAX_N * (x - 1) + y);
		}
		if(x < MAX_M - 1 && b[x + 1][y] == 0  && a[x + 1][y] == f){			//下块进栈 
			s.push(MAX_N * (x + 1) + y);
		}		
	}while(!s.empty());
	return;
}   

int main(){
	int m,n;
	scanf("%d%d",&m,&n);
	MAX_M = m;
	MAX_N = n;
	
	int** a;  //存储数组 
	int** b;  //访问数组 
	
	a = (int**)malloc(sizeof(int*) * m);  //使用malloc二维数组,先sizeof(int*) * 行数,再在for循环中sizeof(int) * 列数 
    for(int i = 0;i < m;i++){
		a[i] = (int*)malloc(sizeof(int) * n);  
	} 
	
	b = (int**)malloc(sizeof(int*) * m);
    for(int i = 0;i < m;i++){
		b[i] = (int*)malloc(sizeof(int) * n);  
	}  
    
    for(int i = 0;i < m;i++){
    	for(int j = 0;j < n;j++){
    		scanf("%d",&a[i][j]);   
    		b[i][j] = 0;            //未访问为0 
		}
	} 
	
	int num = 0;
	for(int i = 0;i < m;i++){
		for(int j = 0;j < n;j++){
			if(b[i][j] == 0){
				DFS(a,b,i,j);  //如果该点未被访问过,则将该点进行DFS,并将符合条件的点的对应访问数组置1 
				num++;
			}
		}
	}	
	printf("%d",num);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/jh8w8m/article/details/87687837