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\n",ans);
69     }
70     return 0;
71 }

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 }

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\n",ans);
105     }
106     return 0;
107 }

end

时间: 2024-10-07 22:52:52

2014 ACM/ICPC Asia Regional Guangzhou Online的相关文章

2014 ACM/ICPC Asia Regional Guangzhou Online Wang Xifeng&#39;s Little Plot HDU5024

一道好枚举+模拟题目.转换思维视角 这道题是我做的,规模不大N<=100,以为正常DFS搜索,于是傻乎乎的写了起来.各种条件限制模拟过程 但仔细一分析发现对每个点进行全部八个方向的遍历100X100X100^8 .100X100个点,每个点在走的时候8中选择,TLE 于是改为另一个角度: 以符合要求的点为拐弯点,朝两个垂直的方向走,求出最远的距离.这样只要对每个点各个方向的长度知道,组合一下对应的就OK. 避免了每个点深搜. PS:搜索的时候x,y写反了,导致构图出现问题,以后用[dy][dx]

poj 5024&amp;&amp;&amp;2014 ACM/ICPC Asia Regional Guangzhou Online 1003(预处理)

http://acm.hdu.edu.cn/showproblem.php?pid=5024 分析:预处理每个点在八个方向的射线长度,再枚举八种L形状的路,取最大值. 注意题意是求一条最长路,要么一条直线,要么只有一个90角,即L型.其实直线就是L形的一个方向长度为0. 代码: #include<iostream> #include<map> #include<cstdio> #include<string> #include<cstring>

HDU 5029 Relief grain(离线+线段树+启发式合并)(2014 ACM/ICPC Asia Regional Guangzhou Online)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5029 Problem Description The soil is cracking up because of the drought and the rabbit kingdom is facing a serious famine. The RRC(Rabbit Red Cross) organizes the distribution of relief grain in the disa

HDU 5014 Number Sequence(2014 ACM/ICPC Asia Regional Xi&#39;an Online) 题解

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5014 Number Sequence Problem Description There is a special number sequence which has n+1 integers. For each number in sequence, we have two rules: ● ai ∈ [0,n] ● ai ≠ aj( i ≠ j ) For sequence a and sequ

hdu 5008(2014 ACM/ICPC Asia Regional Xi&#39;an Online ) Boring String Problem(后缀数组&amp;二分)

Boring String Problem Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 219    Accepted Submission(s): 45 Problem Description In this problem, you are given a string s and q queries. For each que

2014 ACM/ICPC Asia Regional Xi&#39;an Online

03 hdu5009 状态转移方程很好想,dp[i] = min(dp[j]+o[j~i]^2,dp[i]) ,o[j~i]表示从j到i颜色的种数. 普通的O(n*n)是会超时的,可以想到o[]最大为sqrt(n),问题是怎么快速找到从i开始往前2种颜色.三种.四种...o[]种的位置. 离散化之后,可以边走边记录某个数最后一个出现的位置,初始为-1,而所要求的位置就等于 if(last[a[i]]==-1) 该数没有出现过,num[i][1] = i,num[i][j+1] = num[i-1

HDU 5000 2014 ACM/ICPC Asia Regional Anshan Online DP

Clone Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/65536K (Java/Other) Total Submission(s) : 8   Accepted Submission(s) : 5 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description After eating food from Chernobyl,

2014 ACM/ICPC Asia Regional Xi&#39;an Online(HDU 5007 ~ HDU 5017)

题目链接 A题:(字符串查找,水题) 题意 :输入字符串,如果字符串中包含“ Apple”, “iPhone”, “iPod”, “iPad” 就输出 “MAI MAI MAI!”,如果出现 “Sony” 就输出“SONY DAFA IS GOOD!” ,大小写敏感. 思路 : 字符串查找,水题. 1 #include <string.h> 2 #include <stdio.h> 3 #include <iostream> 4 5 using namespace st

HDU 5014 Number Sequence 贪心 2014 ACM/ICPC Asia Regional Xi&#39;an Online

尽可能凑2^x-1 #include <cstdio> #include <cstring> const int N = 100005; int a[N], p[N]; int init(int x) { int cnt = 0; while(x > 1) { x /= 2; cnt ++; } return cnt + 1; } int main() { int n; while(~scanf("%d", &n)){ for(int i = 0;