/*给定一个字符串,计算字符串中数值的个数并求和。其中还包含了负号,若
紧跟负号的是一个数值,则表示这是一个负数,若后面跟着的不是数字,则不表
示什么。
输入:一个字符串
输出:数值个数 数值和
列子
输入: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;
}