• 【POJ】2329 Nearest number


    题目

    传送门:QWQ

    分析

    在dp分类里做的,然而并不会$ O(n^3) $ 的$ dp $,怒写一发搜索。

    看起来是$ O(n^4) $,但仔细分析了一下好像还挺靠谱的?

    poj挂了,没在poj交,在zoj上交的500ms

    P.S. 如果要在poj交还要把多数据改成单数据

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=250;
    int A[maxn][maxn], num[maxn*maxn], id[1000005], cnt, ok[maxn][maxn], n;
    int now[maxn][maxn], ans[maxn][maxn], can[maxn][maxn], vis[maxn][maxn];
    int dx[4]={0,0,1,-1}, dy[4]={1,-1,0,0};
    
    struct Node{ int x,y,dis,numm; };
    
    bool in(int x,int y){ return x>=1&&x<=n&&y>=1&&y<=n; }
    
    queue<Node> que;
    void bfs(int x,int y,int dis,int numm){
        que.push((Node){x,y,dis,numm});
        while(!que.empty()){
            Node a=que.front(); que.pop();
            x=a.x; y=a.y; dis=a.dis++; numm=a.numm;
            for(int i=0;i<4;i++){
                int px=x+dx[i], py=y+dy[i]; 
                if(!in(px,py) || vis[px][py] || ok[px][py]) continue;
                vis[px][py]=1; a.x=px; a.y=py;
                if(dis< now[px][py]){ans[px][py]=numm;can[px][py]=0;now[px][py]=dis;}
                if(dis==now[px][py]){can[px][py]++;}
                que.push(a);
            }
        }
        
    }
    int main(){
        int t; scanf("%d",&t);
        while(t--){
            cnt=0; memset(id,0,sizeof(id)); memset(num,0,sizeof(num)); memset(ok,0,sizeof(ok));
            memset(ans,0,sizeof(ans)); memset(can,0,sizeof(can));
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                scanf("%d",&A[i][j]);
                if(A[i][j]) id[A[i][j]]=++cnt, num[cnt]=A[i][j], ok[i][j]=1;
            }
            memset(now,127,sizeof(now));
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                if(!ok[i][j]) continue;
                vis[i][j]=1; bfs(i,j,1,id[A[i][j]]);
                memset(vis,0,sizeof(vis));
            }
            for(int i=1;i<=n;i++){
                for(int j=1;j<n;j++){
                    if(!ok[i][j] && can[i][j]==1) printf("%d ",num[ans[i][j]]);
                    else printf("%d ",A[i][j]);
                }
                if(!ok[i][n] && can[i][n]==1) printf("%d
    ",num[ans[i][n]]);
                    else printf("%d
    ",A[i][n]);
            }
            
            if(t!=0) puts("");
        }
        return 0;
    }
  • 相关阅读:
    使用批处理文件轻松更改本地IP地址
    Aveiconifier是一个非常实用方便的制作ico格式文件的小工具~
    C#中选择文件的例子
    WindowsXP命令行修改服务启动选项
    Oracle中数据导入导出技巧
    hibernateTemplateOrder Results
    如何向 Microsoft 管理控制台添加证书管理器
    maven usages
    让Eclipse拥有像Visual Studio一样的强大的提示功能
    jsp页面跳转方法及区别
  • 原文地址:https://www.cnblogs.com/noblex/p/9193511.html
Copyright © 2020-2023  润新知