30天编程练习(十一)

本文解析了迷宫问题和规律题的算法实现,通过BFS遍历寻找最优路径,并利用数学方法解决特殊规律问题。

1044 迷宫问题

题意:你,冒险家,在一个危险的地牢里。你被告知地牢要倒塌了。你必须在规定的时间内找到出口楼梯。但是,你不想空手离开地牢。地牢里有很多稀有的珠宝。在你离开之前试着收集一些。有些珠宝便宜,有些贵。所以你会尽最大努力最大化你的收藏,更重要的是,及时离开地牢。
解析:BFS构建一个珠宝和珠宝以及珠宝和出入口之间的网络。

#include <cstdio> 
#include <cstring> 
#include <queue> 
using namespace std; 
 
const int maxn=55; 
int n,m,t,x1,y1,x2,y2; 
struct node 

    int x,y; 
    int zb; 
    int step; 
} ft,et; 
char ap[maxn][maxn]; 
int h[11]; 
bool vis[1100][maxn][maxn]; 
int dir[4][2]= {{-1,0},{1,0},{0,-1},{0,1}}; 
 
int cal(int zb) 

    int i,j,ans=0; 
    for(i=0,j=1; i<10; i++,j=j*2) 
        if(j&zb) ans+=h[i]; 
    return ans; 

void bfs() 

    memset(vis,false,sizeof(vis)); 
    int i,j,ans=-1; 
    ft.x=x1,ft.y=y1,ft.zb=ft.step=0; 
    vis[0][x1][y1]=true; 
    queue<node>q; 
    q.push(ft); 
    while(!q.empty()) 
    { 
        ft=q.front(); 
        q.pop(); 
 
        for(i=0; i<4; i++) 
        { 
            et.x=ft.x+dir[i][0]; 
            et.y=ft.y+dir[i][1]; 
            if(et.x<0||et.y<0||et.x>=n||et.y>=m||ap[et.x][et.y]=='*')continue; 
            if(ap[et.x][et.y]!='.')et.zb=(ft.zb|(1<<(ap[et.x][et.y]-'A'))); 
            else et.zb=ft.zb; 
            if(vis[et.zb][et.x][et.y])continue; 
            vis[et.zb][et.x][et.y]=true; 
            et.step=ft.step+1; 
            if(et.x==x2&&et.y==y2) 
                ans=max(ans,cal(et.zb)); 
            if(et.step==t)continue; 
            q.push(et); 
        } 
    } 
    if(ans==-1)printf("Impossible\n"); 
    else printf("The best score is %d.\n",ans); 

int main() 

    int T,tt=0; 
    scanf("%d",&T); 
    while(T--) 
    { 
        int i,j,k; 
        scanf("%d%d%d%d",&m,&n,&t,&k); 
        for(i=0; i<k; i++)scanf("%d",&h[i]); 
        for(i=0; i<n; i++) 
            scanf("%s",ap[i]); 
        for(i=0; i<n; i++) 
        { 
            for(j=0; j<m; j++) 
            { 
                if(ap[i][j]=='@') 
                { 
                    x1=i; 
                    y1=j; 
                    ap[i][j]='.'; 
                } 
                else if(ap[i][j]=='<') 
                { 
                    x2=i; 
                    y2=j; 
                    ap[i][j]='.'; 
                } 
            } 
        } 
        printf("Case %d:\n",++tt); 
        bfs(); 
        if(T!=0)printf("\n"); 
    } 
    return 0; 

1046 规律题

解析:若两条边中有一条边为偶数,那么走过的路劲的总和一定等于这个矩形的外边长,即 a * b;若 两条边中两条边都为奇数 ,那么一定要走过一条斜边 ,所以结果 等于 a * b - 1 + √2。


#include<stdio.h> 
#include<string.h> 
#include<algorithm> 
using namespace std; 
int flag=1,k; 
int m,n;  
int main() 

    scanf("%d",&k); 
    while(k--) 
    { 
        scanf("%d%d",&m,&n); 
        if(m%2&&n%2) 
        { 
            double ans=m*1.0*n*1.0+1.41-1; 
            printf("Scenario #%d:\n",flag++); 
            printf("%.2lf\n",ans); 
        } 
        else 
        { 
            double ans=m*1.0*n*1.00; 
            printf("Scenario #%d:\n",flag++); 
            printf("%.2lf\n",ans); 
        } 
        printf("\n"); 
    } 


1047 大数求和

解析:大数问题,输入字符串,再让字符串转化为数组,求和,最后按位输出。


#include<stdio.h>
#include<string.h>
int a[110];
char s[110],str[110];
void add(char s[],int a[])
{
    int b[110];
    int i,j,len;
    memset(b,0,sizeof(b));
    len=strlen(s);
    for(i=0;i<len;i++)
    {
        b[len-i-1]=s[i]-'0';
    }
    for(i=0;i<len;i++)
    {
        a[i]=a[i]+b[i];
        if(a[i]>9)
        {
          a[i]=a[i]-10;
          a[i+1]++;
        }
       
    }
}
int main()
{
    int n,i,j;
    scanf("%d",&n);
    while(n--)
    {
        memset(a,0,sizeof(a));
        while(scanf("%s",&str)&&strcmp(str,"0")!=0)
        add(str,a);
        for(i=109;i>0;i--)
        {
            if(a[i]!=0)
            break;
        }
        for(;i>=0;i--)
        {
            printf("%d",a[i]);
        }
        printf("\n");
        if(n!=0)
        {
            printf("\n");
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值