| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4809 人关注过本帖
标题:求教各位一道题
只看楼主 加入收藏
sunyh1999
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:14
帖 子:1178
专家分:3032
注 册:2009-5-17
收藏
得分:0 
回复 20楼 jack10141
我现在做的这个代码,你看看如何做search?

欢迎来到我的博客:http://blog..cn/noisunyuhong
2010-09-14 19:36
sunyh1999
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:14
帖 子:1178
专家分:3032
注 册:2009-5-17
收藏
得分:0 
刚刚又写了个text_data:
程序代码:
#include <stdio.h>
#include <stdlib.h>
#define MAXL 20//定义了block二维数组的最大值为20*20的矩阵
int blackcount=0,blackcounterd[MAXL][MAXL]={0};//blackcount为记录有几个连通块,blackcounter为标记
void text_data(int x[MAXL],int y[MAXL],int pieces[MAXL],int m)// 校验
{
    int i;
    for(i=0;i<n;i++)
    {
    if(x[i]<1||x[i]>n)
    {
        printf("Your input data is error!");
        getchar();
        exit(0);
    }
    if(y[i]<1||y[i]>n)
    {
        printf("Your input data is error!");
        getchar();
        exit(0);
    }
    if(pieces[i]!=0&&pieces[i]!=1)
    {
        printf("Your input data is error");
        getchar();
        exit(0);
    }
    }
}
void search_pieces(int x[MAXL],int y[MAXL],int block[MAXL][MAXL],int pieces[MAXL],int m,int n)//查找连通块
{
    int i,j;
    for(i=0;i<n;i++)
    for(j=0;j<n;j++)

}
void put_pieces(int x[MAXL],int y[MAXL],int block[MAXL][MAXL],int pieces[MAXL],int m)//摆放棋子
{
    int i;
    for(i=0;i<m;i++)
    block[x[i]][y[i]]=pieces[i];//将棋子的值赋给棋盘
}
void main()
{
    int x[MAXL],y[MAXL],block[MAXL][MAXL],pieces[MAXL],i,j,n,m;//block为棋盘,i,j为循环用,x,y为坐标。
    scanf("%d %d",&n,&m);//n为用户定义数组的大小,m为共放了几个棋子
    for(i=0;i<n;i++)
    for(j=0;j<n;j++)
    block[i][j]=-1;//将棋盘全部赋给-1值,因为0是白棋,1是黑棋
    for(i=0;i<n;i++)
    scanf("%d %d %d %d",&pieces[i],&x[i],&y[i]);//输入棋子的颜色,坐标
    text_data(x,y,pieces,m,n);//测试数据,将不正确的输入报错
    put_pieces(x,y,block,pieces,m);//将坐标,棋盘,颜色,基本信息,传入摆放棋子函数中
    search_pieces(x,y,block,pieces,m,n);//search_pieces为查找棋子有几个连通块
}

 

欢迎来到我的博客:http://blog..cn/noisunyuhong
2010-09-14 19:43
jack10141
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:陕西西安
等 级:小飞侠
威 望:6
帖 子:706
专家分:2271
注 册:2010-8-10
收藏
得分:0 
具体实现思路,你看看这个页面吧:方法介绍的比较多
http://hi.baidu.com/qteqpid_pku/blog/item/fcb366eeeb0d182f2cf53464.html

Coding就像一盒巧克力,你永远不会知道你会遇到什么BUG
别跟我说你是不能的,这让我愤怒,因为这侮辱了你的智慧
2010-09-14 19:53
mysky2001
Rank: 2
等 级:论坛游民
帖 子:10
专家分:18
注 册:2010-5-22
收藏
得分:0 
#include<stdio.h>

int main()
{
    int m , n , k = 0 , a[10][10];
    printf("请输入:");
    scanf("%d%d",&m,&n);

    for(int i = 0 ; i < m ; i ++)
    {
        for(int j = 0 ; j < n ; j ++)
        {
            scanf("%d", &a[i][j]);
        }
    }

    for(i = 0 ; i < m ; i ++)
    {
        for(int j = 0 ; j < n ; j ++)
        {
            if(j + 1 < n && a[i][j] == a[i][j + 1]) k ++;
            if(i + 1 < m && a[i][j] == a[i + 1][j]) k ++;
        }
    }
    printf("%d\n",k);
    return 0;
}写的应该可以实现你说的功能
2010-09-14 20:08
mysky2001
Rank: 2
等 级:论坛游民
帖 子:10
专家分:18
注 册:2010-5-22
收藏
得分:0 
刚看了一下,我把题目理解错了。。。但现在还是没有弄懂题意,郁闷
2010-09-14 20:13
jack10141
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:陕西西安
等 级:小飞侠
威 望:6
帖 子:706
专家分:2271
注 册:2010-8-10
收藏
得分:0 
对于这个题目,因为要求棋子是一个一个按照顺序向棋盘摆放的,是否可以考虑新增棋子对原来棋盘中分块的影响?也就是每增加一个棋子,看它上下左右是否为同种棋子,如果不是同种棋子,则连通块数量++,并且赋予其新的颜色。
如果是同种棋子,则与其连成一块赋予其相关的颜色;同时要考察是否有将原来本不相连的区块连到一起了!如果有这样的情况,则需相应的减少连通块数量!并将多种颜色合并为一种颜色!
好像这样处理起来,对时间、空间要求就低得很多了!空间只要两个N*N的数组就好!没有了大量的时间复杂度未知的递归,运算时间也得到了改观!!看来具体问题真的要具体分析呢!
按照这个思路我写了个参考代码,大家帮忙测试下:
程序代码:
#include <stdio.h>
#include <stdlib.h>

#define MAXL 20              //定义了block棋盘二维数组的最大值为20*20的矩阵
int n,m;                     //n为用户定义数组的大小,m为共放了几个棋子
int block[MAXL][MAXL];       //block为棋盘,
int color[MAXL][MAXL]={0};   //color为染色棋盘,颜色编号1~m,0表示无棋子,不染色
int Color=0;                 //Color 当前颜色
int numcolor=0;              //即时的连通块数目,也就是当前棋盘颜色数
int num[MAXL*MAXL];          //存放每放一个棋子后的numcolor

int Changecolor(int newcolor, int oldcolor) //将old颜色全都换为new颜色
{
    int i,j;
    for(i=1;i<=n;i++)
          for(j=1;j<=n;j++)
           if(color[i][j] == oldcolor) color[i][j] = newcolor;
}
int connected(int x,int y,int a,int b)  //连通相临两点
{
        if(color[x][y]==0)  //尚未染色的情况,与临块颜色相同
            color[x][y]=color[a][b];
        else if(color[x][y]!=color[a][b]) //已染色但是与临连块不同色
        {
            Changecolor(color[x][y],color[a][b]); //统一颜色
            numcolor--;     //颜色数量减少
        }
}

int new_pieces(int x,int y,int b)       //新增棋子后,重新染色
{
    int u=0,d=0,l=0,r=0;      //上下左右四个方向
    if(block[x-1][y] != b && block[x+1][y] != b && block[x][y-1] != b && block[x][y+1] != b )
    {                         //如果该棋子为孤立的
        Color++;              //颜色数增加
        color[x][y]=Color;      //填色
        numcolor++;           //连通块数量也增加
        return 0;
    }
    if(block[x-1][y] == b)    //该棋子上连
        connected( x, y,x-1,y);
    if(block[x+1][y] == b)    //该棋子下连
        connected( x, y,x+1,y);
    if(block[x][y-1] == b)    //该棋子左连
        connected( x, y,x,y-1);
    if(block[x][y+1] == b)    //该棋子右连
        connected( x, y,x,y+1);
}


int main()
{
    int i,j,b,x,y;                     //i,j为循环用,x,y为棋子坐标,b为颜色
    scanf("%d%d",&n,&m);               //n为用户定义数组的大小(边长),m为共放了几个棋子
    for(i=0;i<=n+1;i++)                   //为处理方便,棋盘外围加一圈额外的-1
        for(j=0;j<=n+1;j++)
            block[i][j]=-1;            //将棋盘全部赋给-1值,因为0是白棋,1是黑棋
    for(i=0;i<m;i++)
    {  
        scanf("%d%d%d",&b,&x,&y);      //输入棋子的颜色b,坐标x,y
        block[x][y]=b;                 //存入棋盘
        new_pieces(x,y,b);             //新增棋子后,染色作相应的改变
        num[i]=numcolor;               // 输出颜色数量到数组
    }
    for(i=0;i<m;i++)
    {  
        printf("%d\n",num[i]);       // 输出每一次的颜色数量即连通块数量
    }
}



[ 本帖最后由 jack10141 于 2010-9-14 23:11 编辑 ]

Coding就像一盒巧克力,你永远不会知道你会遇到什么BUG
别跟我说你是不能的,这让我愤怒,因为这侮辱了你的智慧
2010-09-14 20:49
jack10141
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:陕西西安
等 级:小飞侠
威 望:6
帖 子:706
专家分:2271
注 册:2010-8-10
收藏
得分:0 
以下是引用mysky2001在2010-9-14 20:13:54的发言:

刚看了一下,我把题目理解错了。。。但现在还是没有弄懂题意,郁闷
这个题目,其实就是幼儿园小朋友向棋盘上随意放双色棋子,每放一个我们要看一下有几个连通块,等小朋友放完了,我们把连通块的数目顺次输出!

Coding就像一盒巧克力,你永远不会知道你会遇到什么BUG
别跟我说你是不能的,这让我愤怒,因为这侮辱了你的智慧
2010-09-15 11:32
sunyh1999
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:14
帖 子:1178
专家分:3032
注 册:2009-5-17
收藏
得分:0 
我将代码按照你的思路写好了,但是程序遇到某个地方运行不下去,你看看:
程序代码:
#include <stdio.h>
#include <stdlib.h>
#define MAXL 20//定义了block二维数组的最大值为20*20的矩阵
int blackcount=0,blackcounterd[MAXL][MAXL]={0},count_b=0,n=0;//blackcount为染色连通块,blackcounter为标记 ,count_b为记录连通块
void print()//打印结果
{
    printf("%d",count_b);
}
void changecolor(int newcolor,int oldcolor)
{
    int i,j;
    for(i=0;i<n;i++)
    for(j=0;j<n;j++)
        if(blackcounterd[i][j]==oldcolor)blackcounterd[i][j]=newcolor;
}
void text_data(int x[MAXL],int y[MAXL],int pieces[MAXL],int m,int n)// 校验
{
    int i;
    for(i=0;i<n;i++)
    {
    if(x[i]<1||x[i]>n)
    {
        printf("Your input data is error!");
        getchar();
        exit(0);
    }
    if(y[i]<1||y[i]>n)
    {
        printf("Your input data is error!");
        getchar();
        exit(0);
    }
    if(pieces[i]!=0&&pieces[i]!=1)
    {
        printf("Your input data is error");
        getchar();
        exit(0);
    }
    }
}
void connected(int temp_x,int temp_y,int a,int b)
{
if(blackcounterd[temp_x][temp_y]==0)// //尚未染色的情况,与临块颜色相同
blackcounterd[temp_x][temp_y]=blackcounterd[a][b];
else if(blackcounterd[temp_x][temp_y]!=blackcounterd[a][b])
{
    changecolor(blackcounterd[temp_x][temp_y],blackcounterd[a][b]);
    count_b--;
}
}
void search_pieces(int x[MAXL],int y[MAXL],int block[MAXL][MAXL],int pieces[MAXL],int m,int n)//查找连通块
{
    int i,temp_x,temp_y;
    for(i=0;i<n;i++)
    {
       if(block[x[i+1]][y[i]]!=pieces[i]&&block[x[i-1]][y[i]]!=pieces[i]&&block[x[i]][y[i-1]]!=pieces[i]&&block[x[i]][y[i+1]]!=pieces[i])
        //如果这个棋子是孤立的就把色块加一
       {
           blackcount=blackcount+1;
           blackcounterd[x[i]][y[i]]=blackcount;//染色
           count_b++;
       }
       if(block[x[i-1]][y[i]]==pieces[i])//该棋子上连
       {
           temp_x=x[i];temp_y=y[i];//因为不能将数组存入整形变量所以用一个“替身”代替
           connected(temp_x,temp_y,temp_x-1,temp_y);
       }
       if(block[x[i+1]][y[i]]==pieces[i])//下连
       {
            temp_x=x[i];temp_y=y[i];//因为不能将数组存入整形变量所以用一个“替身”代替
           connected(temp_x,temp_y,temp_x+1,temp_y);
       }
       if(block[x[i]][y[i-1]]==pieces[i])//左连
       {
           temp_x=x[i];temp_y=y[i];//因为不能将数组存入整形变量所以用一个“替身”代替
           connected(temp_x,temp_y,temp_x,temp_y-1);
       }
       if(block[x[i]][y[i+1]]==pieces[i])//右连
       {
            temp_x=x[i];temp_y=y[i];//因为不能将数组存入整形变量所以用一个“替身”代替
           connected(temp_x,temp_y,temp_x,temp_y+1);
       }
    }
   
}
void put_pieces(int x[MAXL],int y[MAXL],int block[MAXL][MAXL],int pieces[MAXL],int m)//摆放棋子
{
    int i;
    for(i=0;i<m;i++)
    block[x[i]][y[i]]=pieces[i];//将棋子的值赋给棋盘
}
void main()
{
    int x[MAXL],y[MAXL],block[MAXL][MAXL],pieces[MAXL],i,j,m;//block为棋盘,i,j为循环用,x,y为坐标。
    printf("please input n and m:\n");
    scanf("%d %d",&n,&m);//n为用户定义数组的大小,m为共放了几个棋子
    for(i=0;i<n;i++)
    for(j=0;j<n;j++)
    block[i][j]=-1;//将棋盘全部赋给-1值,因为0是白棋,1是黑棋
    printf("棋盘初始化完毕!请输入数据:\n");
    for(i=0;i<m;i++)
    scanf("%d %d %d",&pieces[i],&x[i],&y[i]);//输入棋子的颜色,坐标
    text_data(x,y,pieces,m,n);//测试数据,将不正确的输入报错
    put_pieces(x,y,block,pieces,m);//将坐标,棋盘,颜色,基本信息,传入摆放棋子函数中
    search_pieces(x,y,block,pieces,m,n);//search_pieces为查找棋子有几个连通块
    print();//打印结果
}




[ 本帖最后由 sunyh1999 于 2010-9-16 07:17 编辑 ]

欢迎来到我的博客:http://blog..cn/noisunyuhong
2010-09-15 20:30
a351357741
Rank: 2
等 级:论坛游民
帖 子:117
专家分:70
注 册:2010-9-15
收藏
得分:0 
感觉是 黑白图像问题 直接用dfs加个标记就好了
2010-09-15 20:32
sunyh1999
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:14
帖 子:1178
专家分:3032
注 册:2009-5-17
收藏
得分:0 
我们用的是foodfill

欢迎来到我的博客:http://blog..cn/noisunyuhong
2010-09-15 20:34
快速回复:求教各位一道题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.035068 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved