| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 843 人关注过本帖
标题:puzzle 问题解决方法 各抒己见
取消只看楼主 加入收藏
fourleaves
Rank: 2
等 级:论坛游民
帖 子:194
专家分:99
注 册:2010-5-8
结帖率:95.65%
收藏
已结贴  问题点数:20 回复次数:5 
puzzle 问题解决方法 各抒己见
拼图游戏
Descr:
拼图游戏是广受欢迎的一种智力游戏,它的变化多端,难度不一,让人百玩不厌。
Alice 买了个拼图,她玩了一下午,终于搞清楚每块拼图的上下左右相邻分别是哪一块
拼图,只剩下最后一步来将整个拼图拼好。
现在请你帮助她,输出最终完成的拼图。

input:
输入第一行包含一个整数 N(1<=N<=40000),表示拼图的块数。
接下来有 N 行,分别表示第 i 块拼图的上、下、左、右四个方向分别是哪块拼图,拼图
编号从 1 开始。如果某个方向没有相邻的拼图块(即拼图在边上),那么这个方向的数字为
0。
(题目保证拼图拼好后是一个矩形,且长和宽都不会超过 200)

output:
输出最终完成的拼图。每行中的拼图块编号用一个空格隔开。行末不要输出空格

输入示例
9
0 7 4 5
4 9 0 7
7 0 9 6
0 2 0 1
0 8 1 0
8 0 3 0
1 3 2 8
5 6 7 0
2 0 0 3

输出示例
4 1 5
2 7 8
9 3 6

福州大学的实验题目,今天来了兴致,想看看他们大一教的如何,就见到了这题,于是乎,就写了一下。本人非福大~,写了下。
我写的程序能能得到正确的结果,但是没有测试数据,也没有福大的学生帐号,无法在那边提交,所以不知道,能否ac。
会的写写,交流下吧,明天贴上我的代码。
搜索更多相关主题的帖子: 拼图 
2013-03-29 01:54
fourleaves
Rank: 2
等 级:论坛游民
帖 子:194
专家分:99
注 册:2010-5-8
收藏
得分:0 
以下是引用czz5242199在2013-3-29 08:22:45的发言:

没账号申请个啊~


没学生帐号,那个不是oj,要他们数计学院的学生才能提交。

再复杂的问题也基于最简单的原理。耐心,耐心!丰富自己!等待时机!
2013-03-29 08:49
fourleaves
Rank: 2
等 级:论坛游民
帖 子:194
专家分:99
注 册:2010-5-8
收藏
得分:0 
回复 3楼 azzbcc
我们思路都差不多,只不过我用的是递归解决,而azzbcc版用链表解决。
都是先找到一个我把它叫做定位元素,就是四个最边角的元素中任选一个。接住这元素实现填充完整个表。

再复杂的问题也基于最简单的原理。耐心,耐心!丰富自己!等待时机!
2013-03-29 09:02
fourleaves
Rank: 2
等 级:论坛游民
帖 子:194
专家分:99
注 册:2010-5-8
收藏
得分:0 
回复 4楼 helloUJS
helloujs读题不仔细,这个不一定是正方形,人家定义的是矩形。

再复杂的问题也基于最简单的原理。耐心,耐心!丰富自己!等待时机!
2013-03-29 09:14
fourleaves
Rank: 2
等 级:论坛游民
帖 子:194
专家分:99
注 册:2010-5-8
收藏
得分:0 
以下是引用helloUJS在2013-3-29 09:40:18的发言:

#include<stdio.h>
#include <math.h>
#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4
main()
{
 unsigned char a[40001][4],c[202][202];
 int N,i,j,k,d[5],rows=0,cols=0;
 scanf("%d",&N);
 for(i=1;i<=N;i++)
   for(j=1;j<=4;j++)
     {
      scanf("%d",&d[j]);
      a[j]=d[j];
      }
 for(k=1;k<=N;k++)     /*查找左上角元素*/
   if(a[k]==0 && a[k][LEFT]==0)
        {
         c[1][1]=k;
         break;
         }
 for(i=1;i<=N;i++)     /*确定行列数*/
   if(a[LEFT]==0)
       rows++;
 cols=N/rows;
for(i=1;i<=rows;i++)
   {
    k=c[1];
    c[1]=a[k][DOWN];
    for(j=1;j<cols;j++)
      {
       k=c[j];
       c[j+1]=a[k][RIGHT];
       }
   }
 for(i=1;i<=rows;i++)
   {
    for(j=1;j<=cols;j++)
       printf("%4d",c[j]);
    printf("\n");
    }   
}是的,把行列数计算出来就是矩形情况


发现思路本质都差不多,不同的是实现的方法,对比了一下,发现用你这中方法应该是最方便的。
不过循环语句还可以再优化下
 for(i=1;i<=N;i++)
   for(j=1;j<=4;j++)
     {
      scanf("%d",&d[j]);
      a[j]=d[j];
      }
可以写成N次循环~,虽然差不到哪去~。

再复杂的问题也基于最简单的原理。耐心,耐心!丰富自己!等待时机!
2013-03-29 10:31
fourleaves
Rank: 2
等 级:论坛游民
帖 子:194
专家分:99
注 册:2010-5-8
收藏
得分:0 
贴上自己的代码,欢饮纠错。
程序代码:
#include <stdio.h>
#include <string.h>
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};//上下左右方向 
typedef    struct state{
    int d[4];
}state;  
int num = 0;//填写个数 
state s[201];
int map[200][200];//
int vis[200][200];//标记是否访问过 
int n;
void write_data(int v,state &ss,int x,int y,int &num);
void print_r();
int main(){
    bool flag = true;
    state temp;
    int v1;
    scanf("%d",&n);
    memset(map,0,sizeof(map));
    memset(vis,false,sizeof(vis));
    for(int i=1; i <= n; i++){
        scanf("%d%d%d%d",&s[i].d[0],&s[i].d[1],&s[i].d[2],&s[i].d[3]);
        if( flag && s[i].d[0] == 0 && s[i].d[2] == 0){
            temp = s[i];
            v1 = i;
            flag = false;
        }
    }
    num = 1;
    write_data(v1,temp,0,0,num);
    print_r();
    return 0;
}
void write_data(int v,state &ss,int x,int y,int &num){//v是当前要填的数据,ss为其对应状态,x,y表示位置,num就是第几个。 
    if(num == n + 1 ){
        return;
    }else{
        if(x < 0 || y < 0 || vis[x][y])
            return;
        map[x][y] = v;
        vis[x][y] = true;
        num++;
        for(int i=0; i < 4 ;i++){
            if(ss.d[i] != 0)
                write_data(ss.d[i],s[ss.d[i]],x + dx[i],y + dy[i],num);
        }
    }
}
void print_r(){
    bool flag = false;
    for(int i = 0;i < 200 ;i++){
        for(int j = 0; j < 200; j++){
                if(map[i][j]){
                    printf("%d ",map[i][j]);
                }else{
                    break;
                }
        }
        printf("\n");
        if(!map[i+1][0])
            break;
    }
}

再复杂的问题也基于最简单的原理。耐心,耐心!丰富自己!等待时机!
2013-03-29 10:36
快速回复:puzzle 问题解决方法 各抒己见
数据加载中...
 
   



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

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