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
输出
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;
}