2014 ACM/ICPC Asia Regional Guangzhou Online

Wang Xifeng's Little Plot http://acm.hdu.edu.cn/showproblem.php?pid=5024

预处理出每个点八个方向能走的最远距离,然后枚举起点,枚举方向,每走一步都要枚举左转和右转的情况,因为预处理好了,所以可以直接算出来。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int M=128;
 5 char a[M][M];
 6 int n,dp[M][M][8];
 7 int dx[]={-1,-1,0,1,1,1,0,-1};
 8 int dy[]={0,1,1,1,0,-1,-1,-1};
 9 bool inside(const int &x,const int &y){
10     if(x>=0&&x<n&&y>=0&&y<n) return true;return false;
11 }
12 int getfar(int x,int y,int dir){
13     int res=0;
14     while(true){
15         x+=dx[dir];
16         y+=dy[dir];
17         if(!inside(x,y)||a[x][y]=='#') break;
18         res++;
19     }
20     return res;
21 }
22 int turnleft(int dir){
23     return (dir+6)%8;
24 }
25 int turnright(int dir){
26     return (dir+2)%8;
27 }
28 int solve(int x,int y,int dir){
29     int res=1,step=1,left=turnleft(dir),right=turnright(dir);
30     while(true){
31         x+=dx[dir];
32         y+=dy[dir];
33         if(!inside(x,y)||a[x][y]=='#') break;
34         step++;
35         res=max(res,step+dp[x][y][left]);
36         res=max(res,step+dp[x][y][right]);
37     }
38     return res;
39 }
40 int main(){
41     while(~scanf("%d",&n),n){
42         for(int i=0;i<n;i++){
43             scanf("%s",a[i]);
44         }
45         for(int i=0;i<n;i++){
46             for(int j=0;j<n;j++){
47                 for(int k=0;k<8;k++){
48                     if(a[i][j]=='#'){
49                         dp[i][j][k]=-1;
50                     }
51                     else{
52                         dp[i][j][k]=getfar(i,j,k);
53                     }
54                 }
55             }
56         }
57         int ans=0;
58         for(int i=0;i<n;i++){
59             for(int j=0;j<n;j++){
60                 if(a[i][j]=='.'){
61                     for(int k=0;k<8;k++){
62                         int now=solve(i,j,k);
63                         ans=max(ans,now);
64                     }
65                 }
66             }
67         }
68         printf("%d
",ans);
69     }
70     return 0;
71 }
View Code

A Corrupt Mayor's Performance Art http://acm.hdu.edu.cn/showproblem.php?pid=5023

成段更新。

 1 #include<cstdio>
 2 #include<cstring>
 3 #define mt(a,b) memset(a,b,sizeof(a))
 4 #define lrrt int L,int R,int rt
 5 #define iall 1,n,1
 6 #define imid int mid=(L+R)>>1
 7 #define lson L,mid,rt<<1
 8 #define rson mid+1,R,rt<<1|1
 9 const int M=1000010;
10 struct T{
11     int cover,lazy;
12 }tree[M<<2];
13 void build(lrrt){
14     tree[rt].cover=2;
15     tree[rt].lazy=0;
16     if(L==R) return ;
17     imid;
18     build(lson);
19     build(rson);
20 }
21 void pushdown(int rt){
22     if(tree[rt].lazy){
23         tree[rt<<1].lazy=tree[rt<<1|1].lazy=tree[rt<<1].cover=tree[rt<<1|1].cover=tree[rt].lazy;
24         tree[rt].lazy=0;
25     }
26 }
27 void pushup(int rt){
28     tree[rt].cover=tree[rt<<1].cover==tree[rt<<1|1].cover?tree[rt<<1].cover:0;
29 }
30 void update(int x,int y,int z,lrrt){
31     if(x<=L&&R<=y){
32         tree[rt].cover=tree[rt].lazy=z;
33         return;
34     }
35     imid;
36     pushdown(rt);
37     if(mid>=x) update(x,y,z,lson);
38     if(mid<y)  update(x,y,z,rson);
39     pushup(rt);
40 }
41 bool vis[32];
42 void query(int x,int y,lrrt){
43     if(L==R){
44         vis[tree[rt].cover]=true;
45         return ;
46     }
47     imid;
48     if(x<=L&&R<=y){
49         if(tree[rt].cover){
50             vis[tree[rt].cover]=true;
51             return ;
52         }
53         pushdown(rt);
54         query(x,y,lson);
55         query(x,y,rson);
56         return ;
57     }
58     pushdown(rt);
59     if(mid>=x) query(x,y,lson);
60     if(mid<y)  query(x,y,rson);
61 }
62 int main(){
63     int n,m,x,y,z;
64     char op[4];
65     while(~scanf("%d%d",&n,&m),n|m){
66         build(iall);
67         while(m--){
68             scanf("%s%d%d",op,&x,&y);
69             if(op[0]=='P'){
70                 scanf("%d",&z);
71                 update(x,y,z,iall);
72             }
73             else{
74                 mt(vis,0);
75                 query(x,y,iall);
76                 bool flag=false;
77                 for(int i=1;i<=30;i++){
78                     if(vis[i]){
79                         if(flag) printf(" ");
80                         printf("%d",i);
81                         flag=true;
82                     }
83                 }
84                 puts("");
85             }
86         }
87     }
88     return 0;
89 }
View Code

Saving Tang Monk http://acm.hdu.edu.cn/showproblem.php?pid=5025

集齐m把钥匙,就可以拯救唐僧,没集齐也可以从他身上踩过去,拿钥匙必须从小到大拿,蛇只要杀一次,所以要记录钥匙的状态和蛇是否被杀的状态。bfs。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cctype>
  4 #include<queue>
  5 #define mt(a,b) memset(a,b,sizeof(a))
  6 using namespace std;
  7 const int M=128;
  8 char a[M][M];
  9 int n,m;
 10 struct Snake{
 11     int x,y;
 12 }ts[8];
 13 struct Q{
 14     int step,sta,x,y,snake;
 15     friend bool operator <(const Q &a,const Q &b){
 16         return a.step>b.step;
 17     }
 18 }now,pre;
 19 priority_queue<Q> q;
 20 bool vis[M][M][1<<9];
 21 int dx[]={0,0,1,-1};
 22 int dy[]={1,-1,0,0};
 23 int getkey(const int &psta,const int &x,const int &y){
 24     int ressta=psta;
 25     if(isdigit(a[x][y])){
 26         int his=a[x][y]-'0';
 27         his=1<<(his-1);
 28         if(his-1==psta){
 29             ressta|=his;
 30         }
 31     }
 32     return ressta;
 33 }
 34 int bfs(){
 35     int ls=0;
 36     for(int i=0;i<n;i++){
 37         for(int j=0;j<n;j++){
 38             if(a[i][j]=='K'){
 39                 now.x=i;
 40                 now.y=j;
 41             }
 42             if(a[i][j]=='S'){
 43                 ts[ls].x=i;
 44                 ts[ls].y=j;
 45                 ls++;
 46             }
 47         }
 48     }
 49     now.snake=0;
 50     now.sta=0;
 51     now.step=0;
 52     mt(vis,0);
 53     vis[now.x][now.y][now.sta]=true;
 54     int End=(1<<m)-1;
 55     while(!q.empty()) q.pop();
 56     q.push(now);
 57     while(!q.empty()){
 58         pre=q.top();
 59         q.pop();
 60         if(a[pre.x][pre.y]=='T'&&pre.sta==End) return pre.step;
 61         for(int i=0;i<4;i++){
 62             int tx=pre.x+dx[i];
 63             int ty=pre.y+dy[i];
 64             if(tx>=0&&tx<n&&ty>=0&&ty<n&&a[tx][ty]!='#'){
 65                 now.sta=getkey(pre.sta,tx,ty);
 66                 if(!vis[tx][ty][now.sta]){
 67                     vis[tx][ty][now.sta]=true;
 68                     now.x=tx;
 69                     now.y=ty;
 70                     now.snake=pre.snake;
 71                     if(a[tx][ty]=='S'){
 72                         int id=0;
 73                         for(int j=0;j<ls;j++){
 74                             if(ts[j].x==tx&&ts[j].y==ty){
 75                                 id=j;
 76                                 break;
 77                             }
 78                         }
 79                         if((now.snake>>id)&1){
 80                             now.step=pre.step+1;
 81                         }
 82                         else{
 83                             now.snake|=(1<<id);
 84                             now.step=pre.step+2;
 85                         }
 86                     }
 87                     else{
 88                         now.step=pre.step+1;
 89                     }
 90                     q.push(now);
 91                 }
 92             }
 93         }
 94     }
 95     return -1;
 96 }
 97 int main(){
 98     while(~scanf("%d%d",&n,&m),n|m){
 99         for(int i=0;i<n;i++){
100             scanf("%s",a[i]);
101         }
102         int ans=bfs();
103         if(ans==-1) puts("impossible");
104         else printf("%d
",ans);
105     }
106     return 0;
107 }
View Code

end

原文地址:https://www.cnblogs.com/gaolzzxin/p/3984227.html