1. 程式人生 > >[NewTrain 10][poj 2329]Nearest Number - 2

[NewTrain 10][poj 2329]Nearest Number - 2

fine val iostream img pri for splay cli unsigned

題面:

http://poj.org/problem?id=2329

題解:

這題有很多做法

1. 搜索 復雜度$O(n^4)$ 但是實際上遠遠達不到這個復雜度 所以可以通過

2. 對於每一個格子,我們枚舉每一行,找到每一行離他最近的格子

當前格子向右移動時,每一行離他最近的格子不可能向左移動,所以復雜度$O(n^3)$

3. dp 一共四個方向 左上到右下 左下到右上 右上到左下 右下到左上

然後分別dp 找到這個方向離他最近的格子 以左上到右下為例 $f[i][j]$可由$f[i-1][j],f[i][j-1],f[i-1][j-1]$轉移得到

復雜度$O(n^2)$

Code:

1. 搜索

技術分享圖片
 1
#include<cmath> 2 #include<math.h> 3 #include<ctype.h> 4 #include<algorithm> 5 #include<bitset> 6 #include<cassert> 7 #include<cctype> 8 #include<cerrno> 9 #include<cfloat> 10 #include<ciso646> 11 #include<climits> 12 #include<clocale> 13
#include<complex> 14 #include<csetjmp> 15 #include<csignal> 16 #include<cstdarg> 17 #include<cstddef> 18 #include<cstdio> 19 #include<cstdlib> 20 #include<cstring> 21 #include<ctime> 22 #include<cwchar> 23 #include<cwctype> 24 #include<deque> 25
#include<exception> 26 #include<fstream> 27 #include<functional> 28 #include<iomanip> 29 #include<ios> 30 #include<iosfwd> 31 #include<iostream> 32 #include<istream> 33 #include<iterator> 34 #include<limits> 35 #include<list> 36 #include<locale> 37 #include<map> 38 #include<memory> 39 #include<new> 40 #include<numeric> 41 #include<ostream> 42 #include<queue> 43 #include<set> 44 #include<sstream> 45 #include<stack> 46 #include<stdexcept> 47 #include<streambuf> 48 #include<string> 49 #include<typeinfo> 50 #include<utility> 51 #include<valarray> 52 #include<vector> 53 #include<string.h> 54 #include<stdlib.h> 55 #include<stdio.h> 56 using namespace std; 57 58 int n; 59 int a[1010][1010]; 60 const int dx[]={1,0,-1,0},dy[]={0,1,0,-1},cx[]={-1,1,1,-1},cy[]={-1,-1,1,1}; 61 62 int bfs(int x,int y,int k){ 63 if(a[x][y]) return a[x][y]; 64 if(k>=2*n-1) return 0; 65 int cnt=0; 66 int ok=0; 67 for(int d=0;d<4;d++){ 68 int nwx=x+k*dx[d],nwy=y+k*dy[d]; 69 for(int i=1;i<=k;i++){ 70 if(nwx>=1 && nwx<=n && nwy>=1 && nwy<=n && a[nwx][nwy]){ 71 if(ok==0){ 72 ok=a[nwx][nwy]; 73 } 74 else{ 75 cnt=1; 76 } 77 } 78 nwx=nwx+cx[d]; 79 nwy=nwy+cy[d]; 80 } 81 } 82 if(cnt==1) return 0; 83 else if(ok) return ok; 84 else return bfs(x,y,k+1); 85 } 86 87 int main(){ 88 scanf("%d",&n); 89 for(int i=1;i<=n;i++) 90 for(int j=1;j<=n;j++) 91 scanf("%d",&a[i][j]); 92 for(int i=1;i<=n;i++){ 93 for(int j=1;j<=n;j++) 94 printf("%d ",bfs(i,j,1)); 95 puts(""); 96 } 97 return 0; 98 }
View Code

2.

技術分享圖片
 1 #include<stdio.h>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<map>
 7 #include<set>
 8 #include<cmath>
 9 #include<iostream>
10 #include<queue>
11 #include<string>
12 using namespace std;
13 typedef long long ll;
14 typedef pair<int,int> pii;
15 typedef long double ld;
16 typedef unsigned long long ull;
17 typedef pair<long long,long long> pll;
18 #define fi first
19 #define se second
20 #define pb push_back
21 #define mp make_pair
22 #define rep(i,j,k)  for(register int i=(int)(j);i<=(int)(k);i++)
23 #define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--)
24 
25 ll read(){
26     ll x=0,f=1;char c=getchar();
27     while(c<0 || c>9){if(c==-)f=-1;c=getchar();}
28     while(c>=0 && c<=9){x=x*10+c-0;c=getchar();}
29     return x*f;
30 }
31 
32 const int maxn=220;
33 int n;
34 int a[maxn][maxn];
35 int col[maxn];
36 int b[maxn][maxn],num[maxn];
37 
38 int main(){
39 #ifdef LZT
40     freopen("in","r",stdin);
41 #endif
42     n=read();
43     rep(i,1,n)
44         rep(j,1,n){
45             a[i][j]=read();
46             if(a[i][j]){
47                 num[i]++;
48                 b[i][num[i]]=j;
49             }
50         }
51     rep(i,1,n){
52         rep(j,1,n) col[j]=1;
53         rep(j,1,n){
54             if(a[i][j]==0){
55                 int mndis=1e9,mn=-1;
56                 rep(k,1,n){
57                     int nw=1e9,xx=-1;
58                     if(col[k]<=num[k] && nw>abs(b[k][col[k]]-j)+abs(k-i)){
59                         nw=abs(b[k][col[k]]-j)+abs(k-i);
60                         xx=a[k][b[k][col[k]]];
61                     }
62                     if(col[k]<num[k]){
63                         int nwdis=abs(b[k][col[k]+1]-j)+abs(k-i);
64                         if(nw>nwdis){
65                             nw=nwdis;
66                             xx=a[k][b[k][col[k]+1]];
67                         }
68                         else if(nw==nwdis){
69                             xx=-1;
70                         }
71                     }
72                     if(mndis>nw){
73                         mndis=nw;mn=xx;
74                     }
75                     else if(mndis==nw){
76                         mn=-1;
77                     }
78                     //cout<<i<<‘ ‘<<j<<‘ ‘<<k<<‘ ‘<<col[k]<<‘ ‘<<xx<<endl;
79                 }
80                 if(mn!=-1) a[i][j]=mn;
81             }
82             rep(k,1,n){
83                 if(col[k]<num[k] && abs(b[k][col[k]]-(j+1))>abs(b[k][col[k]+1]-(j+1))) col[k]++;
84             }
85         }
86     }
87 
88     rep(i,1,n){
89         rep(j,1,n)
90             printf("%d ",a[i][j]);
91         puts("");
92     }
93     return 0;
94 }
View Code

3.

沒寫過

不過應該很好寫

Review:

水題

數據也很水

比如第一個代碼 在所有格子均為0的時候復雜度是嚴格$O(n^4)$的 但是竟然跑得比第二個代碼快300ms。。。

每種做法都挺好想

[NewTrain 10][poj 2329]Nearest Number - 2