AmazingCounters.com

2013 Asia acm Hangzhou Regional Contest 杭州现场赛

 B Stealing Harry Potter's Precious

题目大意:给定一个n*m的地图,某些点可以走,某些点可以走某些点不可以走,给定一个起点,又给出了k个点k<=4,要求从起点经过K个点最短的长度是多少

思路:给每个点标定状态为[x][y][state],state是压缩状态的已经走过需要走过点的集合,然后bfs一下即可

 1 #include<cstdio>
 2 #include<queue>
 3 #include<cstring>
 4 #define maxn 101
 5 using namespace std;
 6 const int dx[10]={0,0,0,1,-1};
 7 const int dy[10]={0,1,-1,0,0};
 8 int map[maxn][maxn],full,n,m,sx,sy,x,y,ma;
 9 char ch[maxn];
10 struct T{int x;int y;int st;int dist;};
11 int cal(int x,int y){if(y<=1)return x;return x|(1<<(y-3));}
12 bool visit[maxn][maxn][16];
13 int bfs(int x,int y)
14 {
15         queue<T>q;T a;
16         a.x=x;a.y=y;a.st=cal(0,map[x][y]);a.dist=0;
17         visit[a.x][a.y][a.st]=1;
18         q.push(a);
19         while(!q.empty())
20         {
21                 T u=q.front();
22                 q.pop();
23                 for(int i=1;i<=4;i++)
24                 {
25                         int xx=u.x+dx[i],yy=u.y+dy[i];
26                         if(xx<1||xx>n||yy<1||yy>m||map[xx][yy]==1)continue;
27                         T v;v.x=xx;v.y=yy;
28                         v.st=cal(u.st,map[xx][yy]);
29                         v.dist=u.dist+1;
30                         if(visit[v.x][v.y][v.st]==1)continue;
31                         visit[v.x][v.y][v.st]=1;
32                         if(v.st==full)
33                         {
34                                 return v.dist;
35                         }
36                         q.push(v);
37                 }
38         }
39         return -1;
40 }
41 int main()
42 {
43         while(scanf("%d%d",&n,&m)!=EOF)
44         {
45                 memset(visit,0,sizeof(visit));
46                 if(n==0 && m==0)break;
47                 for(int i=1;i<=n;i++)
48                 {
49                         scanf("%s",ch+1);
50                         for(int j=1;j<=m;j++)
51                         {
52                                 if(ch[j]=='#')map[i][j]=1;else map[i][j]=0;
53                                 if(ch[j]=='@')sx=i,sy=j;
54                         }
55                 }
56                 int k;
57                 scanf("%d",&k);
58                 full=(1<<k)-1;
59                 for(int i=1;i<=k;i++)
60                 {
61                         scanf("%d%d",&x,&y);
62                         map[x][y]=i+2;
63                 }
64                 printf("%d\n",bfs(sx,sy));
65         }
66     return 0;
67 }
View Code

 

C - Zhuge Liang's Password

题目大意:给出两个矩阵,要求两个矩阵旋转之后的最大重合的数字个数

思路:直接模拟

 1 #include<cstdio>
 2 #include<queue>
 3 #include<cstring>
 4 #define maxn 101
 5 using namespace std;
 6 int a[maxn][maxn],n,b[maxn][maxn];
 7 void rot(){
 8         int c[maxn][maxn]={{0}};
 9         for(int i=1;i<=n;i++)
10                 for(int j=1;j<=n;j++)c[i][j]=a[j][n-i+1];
11         memcpy(a,c,sizeof(a));
12 }
13 int main()
14 {
15         while(scanf("%d",&n)!=EOF){
16                 if(n==0)break;
17                 for(int i=1;i<=n;i++)
18                         for(int j=1;j<=n;j++)scanf("%d",&a[i][j]);
19                 for(int i=1;i<=n;i++)
20                         for(int j=1;j<=n;j++)scanf("%d",&b[i][j]);
21                 int ans=0;
22                 for(int k=1;k<=4;k++){
23                         int temp=0;
24                         rot();
25                         for(int i=1;i<=n;i++)
26                                 for(int j=1;j<=n;j++)
27                                         if(a[i][j]==b[i][j])temp++;
28                         ans=max(ans,temp);
29                 }
30                 printf("%d\n",ans);
31         }
32     return 0;
33 }
View Code

 

posted @ 2015-02-09 21:58  philippica  阅读(298)  评论(0编辑  收藏  举报