zoukankan      html  css  js  c++  java
  • 猫鼠两题:捉猫&&老鼠

    一道抓猫,一道捕鼠。

    抓猫

    (D.pas/c/cpp)
    【 题目描述】
    流浪猫布满城市的每一个角落, 非常影响市容市貌, 作为城市聘请的抓猫者, 你有一种捕捉器, 一定可以捕捉到所有走到里面的猫, 更加幸运的是你有一个非常厉害的动物心理学家, 他可以预测猫在不同位置的行走方向(共有东、 西、 南、 北四种情况)为了节约经费, 问你最少需要多少个捕捉器才能把所有的猫都抓住。
    【 输入格式】
    输入第一行包含两个整数 N 和 M(1<=N,M<=1000),表示城市被划分成 N×M 的网格。 接
    下来 N 行, 每行包含 M 个字符“ E”、“ W”、“ S”、“ N” 代表东、 西、 南、 北 4 个方向, 表示
    当猫在该位置的行走方向, 保证猫不会走出城市区域。
    【 输出格式】
    输出一个整数表示最少需要的捕捉器数。
    【 样例输入输出】
    D.in D.out
    3 4
    SWWW
    SEWN
    EEEN
    2
    【 数据说明】
    40% 1<=N,M<=4
    100% 1<=N,M<=1000
    【 样例说明】 捕鼠器放在( 3,4) 点和( 2,2) 点或( 2,3) 点。


    猫可以在任意位置,但是他们会按照一定的顺序走动,所以他们肯定会走到一个终点,或者走成一个环。所以我们直接模拟他们的路径,将他们走过的路全部连通到一个集合里面,即可完成此题。
    所以,此题有并查集,广搜,深搜等多种解法,我使用广搜写的,(广搜相对较为繁琐)。

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    using namespace std;
    int i,j,k,n,m,tot,ans,head,tail;
    int vis[1005][1005];
    char map[1005][1005];
    struct node{
        int x,y;
    }q[1000005];
    int main()
    {
        scanf("%d%d
    ",&n,&m);
        for(register int i=0;i<n;i++){
          for(register int j=0;j<m;j++){
            scanf("%c",&map[i][j]);if(j==m-1) char c=getchar();
          }
        }
        for(register int i=0;i<n;i++)
         for(register int j=0;j<m;j++){
            if(vis[i][j]==1) continue;
            head=0;tail=1;q[tail].x=i;q[tail].y=j;ans++;vis[i][j]=1;
            while(head<tail){
                head++;
                int u1=q[head].x,u2=q[head].y;
                if(map[u1][u2]=='S'&&vis[u1+1][u2]==0){
                    q[++tail].x=u1+1;q[tail].y=u2;vis[u1+1][u2]=1;
                 }
                if(map[u1][u2]=='W'&&vis[u1][u2-1]==0){
                    q[++tail].x=u1;q[tail].y=u2-1;vis[u1][u2-1]=1;
                 }
                if(map[u1][u2]=='N'&&vis[u1-1][u2]==0){
                    q[++tail].x=u1-1;q[tail].y=u2;vis[u1-1][u2]=1;
                }
                if(map[u1][u2]=='E'&&vis[u1][u2+1]==0){
                    q[++tail].x=u1;q[tail].y=u2+1;vis[u1][u2+1]=1;
                }
                if(vis[u1-1][u2]==0&&map[u1-1][u2]=='S'){
                    q[++tail].x=u1-1;q[tail].y=u2;vis[u1-1][u2]=1;
                }
                if(vis[u1+1][u2]==0&&map[u1+1][u2]=='N'){
                    q[++tail].x=u1+1;q[tail].y=u2;vis[u1+1][u2]=1;
                }
                if(vis[u1][u2-1]==0&&map[u1][u2-1]=='E'){
                    q[++tail].x=u1;q[tail].y=u2-1;vis[u1][u2-1]=1;
                }
                if(vis[u1][u2+1]==0&&map[u1][u2+1]=='W'){
                    q[++tail].x=u1;q[tail].y=u2+1;vis[u1][u2+1]=1;
                }
             }
         }
        printf("%d",ans);
        return 0;
    }
    
    
    
    
    
    

    老鼠

    (mouse.pas/c/cpp)
    【 题目描述】
    最近小 h 家闹鼠灾, 弄得小 h 十分恼火。 为了解决老鼠的问题, 小 h 根据老鼠的特点
    想出了一个方法。 假设小 h 的家是一个 n*n 的格子, 每个格子都有一定的食物, 数量在 0
    到 100 之间, 经过观察, 老鼠的窝在( 1, 1) 的位置, 老鼠吃东西有个特点, 到哪个地方,
    就把这个地方的食物都吃掉, 而且每次都比上一次吃的食物要多, 因此它们总会有个停止的
    地方, 而且, 这些老鼠一次最多可以跳 k 格, 不过只能按 x 轴或 y 轴方向来跳。 现在, 小 h
    给出食物的分布, 他想知道一只老鼠最多可以吃到多少食物。
    【 输入格式】
    第一行,n,(1<=n<=100),k,(0<=k<=n),表示 n*n 的格子, 老鼠一次最多跳 k 格。
    接下来的 n 行, 每行 n 个数, 表示这个方格上的食物数量。
    【 输出格式】
    一个数, 表示一只老鼠最多可以吃到的食物。
    【 样例输入输出】
    mouse.in Mouse.out
    in:3 1
    1 2 5
    10 11 6
    12 12 7

    out:37
    【 样例解释】
    (1,1)->(1,2)->(1,3)->(2,3)->(2,2)->(3,2)
    1+2+5+6+11+12=37

    这题数据范围是100(n) 所以整个棋盘点数100*100=10000个。
    所以普通的搜索无法AC,所以此题要用记忆化搜索,(记忆化搜索,所以DP肯定是可以的,我写的就是DP)。
    我的方法比较玄学。先将所有格子转化成一维数组,然后按米粒数从小到大排序。
    因为我们从(1,1)开始走,所以将(1,1)赋值为有答案,答案为(1,1)的米粒数。
    然后从米粒的大小扫,如果在当前米粒数的那行或那列有小于此格米粒数的格子,且
    当个已被赋值成有值(初始化的时候只有(1,1)赋值成有值,所以可以确保从(1,1)
    往后生成),则当前格子的总值就是那个格子的值加上本格子的米粒数。当然for一
    行一列,要取一个叫max。最后for一遍整张图的值,取max,既是答案。
    代码辅助理解:

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #define C c=getchar()
    using namespace std;
    int j,k,n,m,tot,ans,top;
    int f[105][105],r[105][105];
    struct node{
        int x,y,num,tot;
    }a[10005];
    int cmp(node a,node b){
        if(a.num<b.num) return 1;
        else return 0;
    }
    int read(){
        char c;int x;while(C,c<'0'||c>'9');x=c-'0';
        while(C,c>='0'&&c<='9') x=x*10+c-'0';return x;
    }
    int maxn(int a,int b){return a>b?a:b;}
    int minn(int a,int b){return a<b?a:b;}
    int main()
    {
        n=read();k=read();
        register int i,j;
        for(i=1;i<=n;i++)
         for(j=1;j<=n;j++){
            f[i][j]=read();
            a[++top].x=i;a[top].y=j;a[top].num=f[i][j];
         }
        sort(a+1,a+1+top,cmp);r[1][1]=f[1][1];
        for(i=1;i<=top;i++){
            if(a[i].num==f[1][1]) continue;
            for(j=maxn(a[i].x-k,1);j<=minn(a[i].x+k,n);j++)
            if(f[j][a[i].y]<a[i].num) a[i].tot=maxn(a[i].tot,a[i].num+r[j][a[i].y]);
            for(j=maxn(a[i].y-k,1);j<=minn(a[i].y+k,n);j++)
            if(f[a[i].x][j]<a[i].num) a[i].tot=maxn(a[i].tot,a[i].num+r[a[i].x][j]);
            if(a[i].tot!=a[i].num) r[a[i].x][a[i].y]=a[i].tot;   /*此部判断很重要,以为如果没有其他格子能走到此格,那此格就不能赋
    值为有值。否则其他各会从此格生成,导致答案偏大。(当时我没注意这点,被坑成狗)。*/
        }
        for(i=1;i<=n;i++) 
         for(j=1;j<=n;j++) ans=maxn(ans,r[i][j]);
        if(ans==0) ans=f[1][1];
        printf("%d",ans);
        return 0;
    }
    
    
    
    
    
    
  • 相关阅读:
    sharepoint custom web service
    网站模板创建报错
    sharepoint 2013 持续爬网
    使用 SQL的 for xml path来进行字符串拼接 (group by)
    sharepoint 修改AD密码
    SharePoint 2013 BCS
    系统补丁对sharepoint很重要
    SharePoint 2010: Export User Profile Properties to a Text File or Excel using PowerShell
    SharePoint2013 错误
    sharepoint 开发相关工具总结
  • 原文地址:https://www.cnblogs.com/stevensonson/p/7612210.html
Copyright © 2011-2022 走看看