NYOJ-635 Oh, my goddess C语言

题目:

Oh, my goddess

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 3
描述

Shining Knight is the embodiment of justice and he has a very sharp sword can even cleavewall. Many bad guys are dead on his sword.

One day, two evil sorcerer cgangee and Jackchess decided to give him some colorto see. So they kidnapped Shining Knight's beloved girl--Miss Ice! They built a M x Nmaze with magic and shut her up in it.

Shining Knight arrives at the maze entrance immediately. He can reach any adjacent emptysquare of four directions -- up, down, left, and right in 1 second. Or cleave one adjacent wall in 3

seconds, namely,turn it into empty square. It's the time to save his goddess! Notice: ShiningKnight won't leave the maze before he find Miss Ice.

输入
The input consists of blocks of lines. There is a blank line between two blocks.

The first line of each block contains two positive integers M <= 50 and N <= 50separated by one space. In each of the next M lines there is a string of length N contentsO and #.

O represents empty squares. # means a wall.

At last, the location of Miss Ice, ( x, y ). 1 <= x <= M, 1 <= y <= N.

(Shining Knight always starts at coordinate ( 1, 1 ). Both Shining and Ice's locationguarantee not to be a wall.)
输出
The least amount of time Shining Knight takes to save hisgoddess in one line.
样例输入
3 5
O####
#####
#O#O#
3 4
样例输出
14

代码AC情况:


代码》C语言:

/*堆就是优先队列
我用Tree[3][N]表示节点信息 用Tree[3][N]当最小堆 tree[0]不用 tree[0][0]表示当前堆的数字组数
Tree[0][N]表示X坐标
Tree[1][N]表示Y坐标
Tree[2][N]表示time坐标     
insert(tree,x,y,time)向tree堆里插入 坐标x,y,和在x,y坐标上 已经经历的时间 time
Delmin(tree)删除最小值time及当前的坐标 并维护堆的特性
由这个堆的特性    
{X,Y,time}={Tree[0][1]  Tree[1][1]   Tree[2][1]}一定是这个堆里最小的 因为我的tree[0][0],tree[1][0],tree[2][0]没用到 里面没存储元素
整体思路:
因为#计时为4 O计时为1
所以加入堆后 会弹出一个最小的time
*/
# include <stdio.h>
# define N  124//堆的最大数量
# define M  52//地图最大尺寸
void insert(int Tree[][N],int X,int Y,int time);//向最小堆Tree[]里插入元素{X,Y,time}
void Delmin(int Tree[][N]) ;// 并删除最小值 time 及连带的信息
void Solve(int x,int y);//解决函数
char map[M][M],Flag[M][M];//map存储地图 Flag[i][j]存储当前点(i,j)是否走过 走过为1 没走过为0
int direct[4][2]={{1,0},{-1,0},{0,1},{0,-1}};//通过加direct的数组值改变轨迹
int Tree[3][N],n,m;//地图 长宽 n,m 和Tree[]堆
int main()
{
    int x,y,i,j;
    //freopen("MAPP.txt","r",stdin);
    while(~scanf("%d%d",&n,&m))
    {
        for(i=1;i<=n;i++)
        {
            getchar();  //读掉回车符
            for(j=1;j<=m;j++)
            {
                scanf("%c",&map[i][j]);//读入地图
                Flag[i][j]=0;//初始化标记为0 代表没走过
            }
        }
        scanf("%d%d",&x,&y);//输入终点坐标
        Solve(x,y);
    }
    return 0;
}
void Solve(int x,int y){
    int xx,yy,time,X,Y,i;
    Tree[0][0]=0;//初始化优先队列
    insert(Tree,1,1,0);//在地图左上角的 (1,1)开始走 当前时间为0
    Flag[1][1]=1;         //将 (1,1)的坐标记为走过
    while(Tree[0][0])//当堆里还存在组数时
    {
        xx=Tree[0][1];yy=Tree[1][1];time=Tree[2][1];//记录堆里的最小值time  注释第9行
        Delmin(Tree);//删除最小值time
       if(xx==x&&yy==y)//如果当前的堆里弹出的最小值time 所在的坐标正好为终点
       {
           printf("%d\n",time);//输出
           return ;
       }
       for(i=0;i<4;i++)//不到终点则四个方向遍历
       {
           X=xx+direct[i][0];//改变 X Y坐标 代表四个方向移动
           Y=yy+direct[i][1];
           if(X<1||Y<1||X>n||Y>m)//如果超出了地图尺寸 则continue 
           continue;
           if(!Flag[X][Y])//否则 如果当前没走 则Flag[][]为0
           {
                insert(Tree,X,Y,time+(map[X][Y]=='#'?4:1));//向堆中插入走的路径 X Y 并计算好时间
                Flag[X][Y]=1;//将当前的坐标改为走过
           }
       }
    }
}
void insert(int Tree[][N],int X,int Y,int time) //向最小堆Tree[]里插入元素{X,Y,time}
{
    int par,i=++Tree[0][0],j;  //插入X 后 Tree[0]+1
    while(i>>1)  //直到i不是根节点
    {
       par=(i>>1);  //父节点为par
       if(Tree[2][par]<=time) break;//如果父节点满足最大堆的特性 则插入当前的位置即可
       for(j=0;j<3;j++)
       Tree[j][i]=Tree[j][par]; //否则调整堆 即位置上移
       i=par;
    }
    Tree[0][i]=X;//插入新节点
    Tree[1][i]=Y;
    Tree[2][i]=time;
}
void Delmin(int Tree[][N])  //删除最小值time 及连带的信息
{
   int i=1,j,R,L,S=Tree[0][0];
   int X=Tree[0][S],Y=Tree[1][S],time=Tree[2][S];//X Y time 记录当前末尾节点 
   while((i<<1)<Tree[0][0])
   {
      L=(i<<1);R=L+1;//Left Right 记录左右节点
      if(R<Tree[0][0]&&Tree[2][R]<Tree[2][L])//比较两个子节点的值的大小
                L=R;
      if(Tree[2][L]>=time) break;//如果所有的位置已经调整好 跳出循环
       for(j=0;j<3;j++)
      Tree[j][i]=Tree[j][L];//否则继续调整堆
      i=L;
   }
   Tree[0][0]--;   //总数-1
   Tree[0][i]=X;  //调整好并赋值
   Tree[1][i]=Y;
   Tree[2][i]=time;
}


孪生素数是指两个素数之间的差值为2的素数对。通过筛选法可以找出给定素数范围内的所有孪生素数的组数。 在引用的代码中,使用了递归筛选法来解决孪生素数问题。该程序首先使用循环将素数的倍数标记为非素数,然后再遍历素数数组,找出相邻素数之间差值为2的素数对,并统计总数。 具体实现过程如下: 1. 定义一个数组a[N,用来标记数字是否为素数,其中N为素数范围的上限。 2. 初始化数组a,将0和1标记为非素数。 3. 输入要查询的孪生素数的个数n。 4. 循环n次,每次读入一个要查询的素数范围num。 5. 使用两层循环,外层循环从2遍历到num/2,内层循环从i的平方开始,将素数的倍数标记为非素数。 6. 再次循环遍历素数数组,找出相邻素数之间差值为2的素数对,并统计总数。 7. 输出总数。 至此,我们可以使用这个筛选法的程序来解决孪生素数问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [python用递归筛选法求N以内的孪生质数(孪生素数)](https://blog.csdn.net/weixin_39734646/article/details/110990629)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [NYOJ-26 孪生素数问题](https://blog.csdn.net/memoryofyck/article/details/52059096)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值