5.1 基础题目选讲
11624 - Fire!
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2671
bfs预处理出每个点起火时间,然后再bfs出去到时间。
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int inf=0x3f3f3f3f; 7 const int M=1024; 8 int t,n,m; 9 char a[M][M]; 10 int d[M][M]; 11 int dx[]={0,0,1,-1}; 12 int dy[]={1,-1,0,0}; 13 struct Q{ 14 int x,y,step; 15 }now,pre; 16 queue<Q> q; 17 bool inside(const int &x,const int &y){ 18 if(x>=0&&x<n&&y>=0&&y<m) return true; return false; 19 } 20 void bfs(){ 21 for(int i=0;i<n;i++){ 22 for(int j=0;j<m;j++){ 23 d[i][j]=inf; 24 } 25 } 26 while(!q.empty()) q.pop(); 27 for(int i=0;i<n;i++){ 28 for(int j=0;j<m;j++){ 29 if(a[i][j]=='F'){ 30 now.x=i; 31 now.y=j; 32 now.step=0; 33 d[i][j]=0; 34 q.push(now); 35 } 36 } 37 } 38 while(!q.empty()){ 39 pre=q.front(); 40 q.pop(); 41 for(int i=0;i<4;i++){ 42 int tx=pre.x+dx[i]; 43 int ty=pre.y+dy[i]; 44 if(!inside(tx,ty)||a[tx][ty]=='#') continue; 45 now.step=pre.step+1; 46 if(d[tx][ty]>now.step){ 47 d[tx][ty]=now.step; 48 now.x=tx; 49 now.y=ty; 50 q.push(now); 51 } 52 } 53 } 54 } 55 bool out(const Q &a){ 56 if(a.x==0||a.x==n-1||a.y==0||a.y==m-1) return true; return false; 57 } 58 bool vis[M][M]; 59 int solve(){ 60 mt(vis,0); 61 while(!q.empty()) q.pop(); 62 for(int i=0;i<n;i++){ 63 for(int j=0;j<m;j++){ 64 if(a[i][j]=='J'){ 65 vis[i][j]=true; 66 now.x=i; 67 now.y=j; 68 now.step=0; 69 q.push(now); 70 } 71 } 72 } 73 while(!q.empty()){ 74 pre=q.front(); 75 q.pop(); 76 if(out(pre)) return pre.step+1; 77 for(int i=0;i<4;i++){ 78 int tx=pre.x+dx[i]; 79 int ty=pre.y+dy[i]; 80 if(!inside(tx,ty)||a[tx][ty]=='#'||vis[tx][ty]||d[tx][ty]<=pre.step+1) continue; 81 vis[tx][ty]=true; 82 now.x=tx; 83 now.y=ty; 84 now.step=pre.step+1; 85 q.push(now); 86 } 87 } 88 return -1; 89 } 90 int main(){ 91 while(~scanf("%d",&t)){ 92 while(t--){ 93 scanf("%d%d",&n,&m); 94 for(int i=0;i<n;i++){ 95 scanf("%s",a[i]); 96 } 97 bfs(); 98 int ans=solve(); 99 if(~ans) printf("%d\n",ans); 100 else puts("IMPOSSIBLE"); 101 } 102 } 103 return 0; 104 }
10047 - The Monocycle
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=988
bfs 每个位置x,y 有朝向d,有颜色c,状态是四维的,有三种走法,左右前。
1 #include<cstdio> 2 #include<algorithm> 3 #include<queue> 4 using namespace std; 5 const int inf=0x3f3f3f3f; 6 const int M=32; 7 int n,m; 8 char a[M][M]; 9 int dp[M][M][8][4]; 10 struct Q{ 11 int x,y,step,color,dir; 12 }now,pre; 13 queue<Q> q; 14 int dx[]={-1,0,1,0}; 15 int dy[]={0,1,0,-1}; 16 Q turnright(const Q &pre){ 17 Q now; 18 now.color=pre.color; 19 now.x=pre.x; 20 now.y=pre.y; 21 now.dir=(pre.dir+1)%4; 22 now.step=pre.step+1; 23 return now; 24 } 25 Q turnleft(const Q &pre){ 26 Q now; 27 now.color=pre.color; 28 now.x=pre.x; 29 now.y=pre.y; 30 now.dir=pre.dir-1; 31 if(now.dir==-1) now.dir=3; 32 now.step=pre.step+1; 33 return now; 34 } 35 Q ahead(const Q &pre){ 36 Q now; 37 now.color=(pre.color+1)%5; 38 now.x=pre.x+dx[pre.dir]; 39 now.y=pre.y+dy[pre.dir]; 40 now.dir=pre.dir; 41 now.step=pre.step+1; 42 return now; 43 } 44 bool inside(const Q &now){ 45 if(now.x>=0&&now.x<n&&now.y>=0&&now.y<m) return true; return false; 46 } 47 void go(const Q &now){ 48 if(!inside(now)||a[now.x][now.y]=='#') return ; 49 if(dp[now.x][now.y][now.color][now.dir]>now.step){ 50 dp[now.x][now.y][now.color][now.dir]=now.step; 51 q.push(now); 52 } 53 } 54 void bfs(){ 55 for(int i=0;i<n;i++){ 56 for(int j=0;j<m;j++){ 57 for(int k=0;k<5;k++){ 58 for(int u=0;u<4;u++){ 59 dp[i][j][k][u]=inf; 60 } 61 } 62 } 63 } 64 for(int i=0;i<n;i++){ 65 for(int j=0;j<m;j++){ 66 if(a[i][j]=='S'){ 67 now.x=i; 68 now.y=j; 69 } 70 } 71 } 72 dp[now.x][now.y][0][0]=0; 73 now.color=0; 74 now.dir=0; 75 now.step=0; 76 while(!q.empty()) q.pop(); 77 q.push(now); 78 while(!q.empty()){ 79 pre=q.front(); 80 q.pop(); 81 now=turnright(pre); 82 go(now); 83 now=turnleft(pre); 84 go(now); 85 now=ahead(pre); 86 go(now); 87 } 88 } 89 int main(){ 90 int cas=1; 91 while(~scanf("%d%d",&n,&m),n|m){ 92 for(int i=0;i<n;i++){ 93 scanf("%s",a[i]); 94 } 95 bfs(); 96 int ex,ey; 97 for(int i=0;i<n;i++){ 98 for(int j=0;j<m;j++){ 99 if(a[i][j]=='T'){ 100 ex=i; 101 ey=j; 102 } 103 } 104 } 105 if(cas>1) puts(""); 106 printf("Case #%d\n",cas++); 107 int ans=inf; 108 for(int i=0;i<4;i++){ 109 ans=min(ans,dp[ex][ey][0][i]); 110 } 111 if(ans<inf){ 112 printf("minimum time = %d sec\n",ans); 113 } 114 else{ 115 puts("destination not reachable"); 116 } 117 } 118 return 0; 119 }
10054 - The Necklace
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=995
把颜色当成结点,一个珍珠的两种颜色就连一条边,求无向图欧拉回路,
无向图存在欧拉回路的条件是每个点的出度入度都是偶数
1 #include<cstdio> 2 #include<cstring> 3 #define mt(a,b) memset(a,b,sizeof(a)) 4 const int M=64; 5 int g[M][M],du[M]; 6 void dfs(int u){ 7 for(int i=1;i<=50;i++){ 8 if(g[u][i]){ 9 g[u][i]--; 10 g[i][u]--; 11 dfs(i); 12 printf("%d %d\n",i,u); 13 } 14 } 15 } 16 int main(){ 17 int t,n,u,v; 18 while(~scanf("%d",&t)){ 19 for(int cas=1;cas<=t;cas++){ 20 scanf("%d",&n); 21 mt(g,0); 22 mt(du,0); 23 while(n--){ 24 scanf("%d%d",&u,&v); 25 g[u][v]++; 26 g[v][u]++; 27 du[u]++; 28 du[v]++; 29 } 30 bool flag=false; 31 for(int i=1;i<=50;i++){ 32 if(du[i]&1){ 33 flag=true; 34 break; 35 } 36 } 37 if(cas>1) puts(""); 38 printf("Case #%d\n",cas); 39 if(flag){ 40 puts("some beads may be lost"); 41 continue; 42 } 43 dfs(u); 44 } 45 } 46 return 0; 47 }
4255 - Guess
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=&problem=2256&mosmsg=Submission+received+with+ID+1596529
ans[]记录前n项和,+号说明Ax+...Ay>0 ==> Sumy-Sum(x-1)>0 ==> Sumy>Sum(x-1) 负号同理,就能得到前n项和之间的大小关系,可以根据大于的关系建一条有向边,然后边拓扑排序边更新ans。这里采用的是至少要少1,因为答案不唯一。
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int M=32; 7 char a[M]; 8 struct G{ 9 struct E{ 10 int v,next; 11 }e[M*M]; 12 int le,head[M]; 13 void init(){ 14 le=0; 15 mt(head,-1); 16 } 17 void add(int u,int v){ 18 e[le].v=v; 19 e[le].next=head[u]; 20 head[u]=le++; 21 } 22 }g; 23 int t,n,rudu[M],ans[M]; 24 queue<int> q; 25 void toposort(){ 26 mt(ans,0); 27 while(!q.empty()) q.pop(); 28 for(int i=0;i<=n;i++){ 29 if(!rudu[i]) q.push(i); 30 } 31 while(!q.empty()){ 32 int u=q.front(); 33 q.pop(); 34 for(int i=g.head[u];~i;i=g.e[i].next){ 35 int v=g.e[i].v; 36 ans[v]=min(ans[v],ans[u]-1); 37 rudu[v]--; 38 if(!rudu[v]){ 39 q.push(v); 40 } 41 } 42 } 43 } 44 int main(){ 45 while(~scanf("%d",&t)){ 46 while(t--){ 47 scanf("%d%s",&n,a); 48 int p=0; 49 g.init(); 50 mt(rudu,0); 51 for(int i=1;i<=n;i++){ 52 for(int j=i;j<=n;j++){ 53 if(a[p]=='-'){ 54 g.add(i-1,j); 55 rudu[j]++; 56 } 57 else if(a[p]=='+'){ 58 g.add(j,i-1); 59 rudu[i-1]++; 60 } 61 p++; 62 } 63 } 64 toposort(); 65 for(int i=1;i<=n;i++){ 66 printf("%d ",ans[i]-ans[i-1]); 67 } 68 puts(""); 69 } 70 } 71 return 0; 72 }
vector存图
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<queue> 5 #define mt(a,b) memset(a,b,sizeof(a)) 6 using namespace std; 7 const int M=32; 8 char a[M]; 9 vector<int> g[M]; 10 int t,n,rudu[M],ans[M]; 11 queue<int> q; 12 void toposort(){ 13 mt(ans,0); 14 while(!q.empty()) q.pop(); 15 for(int i=0;i<=n;i++){ 16 if(!rudu[i]) q.push(i); 17 } 18 while(!q.empty()){ 19 int u=q.front(); 20 q.pop(); 21 int len=g[u].size(); 22 for(int i=0;i<len;i++){ 23 int v=g[u][i]; 24 ans[v]=min(ans[v],ans[u]-1); 25 rudu[v]--; 26 if(!rudu[v]){ 27 q.push(v); 28 } 29 } 30 } 31 } 32 int main(){ 33 while(~scanf("%d",&t)){ 34 while(t--){ 35 scanf("%d%s",&n,a); 36 int p=0; 37 for(int i=0;i<=n;i++) g[i].clear(); 38 mt(rudu,0); 39 for(int i=1;i<=n;i++){ 40 for(int j=i;j<=n;j++){ 41 if(a[p]=='-'){ 42 g[i-1].push_back(j); 43 rudu[j]++; 44 } 45 else if(a[p]=='+'){ 46 g[j].push_back(i-1); 47 rudu[i-1]++; 48 } 49 p++; 50 } 51 } 52 toposort(); 53 for(int i=1;i<=n;i++){ 54 printf("%d ",ans[i]-ans[i-1]); 55 } 56 puts(""); 57 } 58 } 59 return 0; 60 }
end