Problem A Inna and Pink Pony
题意:这一题实在太逗了。。。两个小时都在搞这一题。给一个n*m的棋盘。初始点在(x,y)然后有四种变幻(x+a,y-b)(x+a,y+b)(x-a,y-b)(x-a,y+b)。问你最少几步能到棋盘的四角。
解法:先判断能不能走到,能走到的一定是x,y方向差值能整除a,b的。然后他们的商之和为偶数。(这个画一个图很好理解)最后判一下棋盘的长宽必须大于a,b(易错!)若是不满足除非起始点就在四角否则走不到。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <utility> 7 #include <queue> 8 #include <stack> 9 #include <vector> 10 #define ll long long 11 #define INF 0x7fffffff 12 #define eps 1E-6 13 #define mp(a,b) make_pair(a,b) 14 15 using namespace std; 16 17 typedef pair<int, int> pii; 18 19 int n, m; 20 21 int _abs(int x){return x>0?x:-x;} 22 bool j(int a,int b){return (a/(b*1.0)-a/b)==0;} 23 24 int main() 25 { 26 // freopen("in.txt", "r", stdin); 27 28 int x, y, a, b; 29 while(cin >> n >> m >> x >> y >> a >> b){ 30 int ans=INF; 31 if((x==1 && y==1) || (x==1 && y==m) || (x==n && y==1) || (x==n && y==m)) ans = 0; 32 int tx = _abs(1-x),ty = _abs(1-y),ex = _abs(n-x), ey = _abs(m-y); 33 if(j(tx,a) && j(ty, b) && (tx/a+ty/b)%2==0 && (tx>=a || ex>=a) && (ty>=b || ey>=b))ans = min(ans, max(tx/a, ty/b)); 34 if(j(ex,a) && j(ey, b) && (ex/a+ey/b)%2==0 && (tx>=a || ex>=a) && (ty>=b || ey>=b))ans = min(ans, max(ex/a, ey/b)); 35 if(j(tx,a) && j(ey, b) && (tx/a+ey/b)%2==0 && (tx>=a || ex>=a) && (ty>=b || ey>=b))ans = min(ans, max(tx/a, ey/b)); 36 if(j(ex,a) && j(ty, b) && (ex/a+ty/b)%2==0 && (tx>=a || ex>=a) && (ty>=b || ey>=b))ans = min(ans, max(ex/a, ty/b)); 37 38 if(ans == INF)cout << "Poor Inna and pony!" << endl; 39 else cout << ans << endl; 40 } 41 return 0; 42 }
Problem B Inna and Nine
题意:大水题每个数字能和前面一个数字合并,统计最后合并数字9个数最多的有几个?
思路:大水题。。。比赛的时候竟然没发现。只要简单统计一下连续能合并出来的9的个数若是奇数个不用管他,偶数个就直接答案乘上cnt/2+1即可。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <utility> 7 #include <queue> 8 #include <stack> 9 #include <vector> 10 #define ll long long 11 #define INF 0x7fffffff 12 #define eps 1E-6 13 #define LEN 100100 14 #define mp(a,b) make_pair(a,b) 15 16 using namespace std; 17 18 typedef pair<int, int> pii; 19 char str[LEN]; 20 ll num[LEN], len; 21 22 void init() 23 { 24 for(int i=0; i<len; i++){ 25 num[i] = str[i]-'0'; 26 } 27 } 28 29 int main() 30 { 31 // freopen("in.txt", "r", stdin); 32 33 while(cin >> str){ 34 len = strlen(str); 35 init(); 36 ll tcnt = 0, ans = 1; 37 for(int i=0; i<len; i++){ 38 if(num[i]+num[i-1] == 9){ 39 tcnt++; 40 continue; 41 } 42 if(tcnt && tcnt%2==0){ 43 ans *= (tcnt/2+1); 44 } 45 tcnt = 0; 46 } 47 if(tcnt%2==0){ 48 ans *= tcnt/2+1; 49 } 50 cout << ans << endl; 51 } 52 return 0; 53 }
Problem C Inna and Dima
题意:在一个地图中寻找最长的DIMA循环序列,格子能重复走。问最长的有多少个?如果有无穷个输出Poor Inna!没有输出Poor Dima!。
思路:这题一看就知道是记忆化搜索的问题。动态规划方程也很好确定就是f[i][j]为(i,j)开始最长的DIMA序列循环个数。至于要怎么处理无限长的问题上我想了好长时间。最后想出来一个很挫的办法。不过还是能解决问题0.0
首先就是f[i][j] = max(f[tx][ty]周围的四个点)若这格是A下一个是D的话+1。还有如果结束是A返回1否则0。当你推出了最大的解之后这并不是正确答案,还要确定的是有没有环。我是遍历一下整个地图寻找有没有一个格子它的下一步是可走的然后记录的那个值还是比他大,若当前这格是A的话可以相等(样例2)。若是存在这种情况我们就知道在图中有环了。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <utility> 7 #include <queue> 8 #include <stack> 9 #include <vector> 10 #define ll long long 11 #define INF 0x7fffffff 12 #define eps 1E-6 13 #define LEN 1010 14 #define mp(a,b) make_pair(a,b) 15 16 using namespace std; 17 18 typedef pair<int, int> pii; 19 int n, m, Map[LEN][LEN], f[LEN][LEN]; 20 int xx[] = {0, 0, 1,-1}; 21 int yy[] = {1,-1, 0, 0}; 22 23 int dp(int x, int y, int st){ 24 if(st >= n*m) return INF; 25 if(f[x][y]!=-1)return f[x][y]; 26 int ret = Map[x][y]=='A'?1:0; 27 for(int i=0; i<4; i++){ 28 int tx = x+xx[i]; 29 int ty = y+yy[i]; 30 if(tx>=0 && tx<n && ty>=0 && ty<m){ 31 if(Map[x][y]=='D' && Map[tx][ty]=='I')ret = max(ret, dp(tx, ty, st+1)); 32 if(Map[x][y]=='I' && Map[tx][ty] == 'M')ret = max(ret, dp(tx, ty, st+1)); 33 if(Map[x][y]=='M' && Map[tx][ty] == 'A')ret = max(ret, dp(tx, ty, st+1)); 34 if(Map[x][y]=='A' && Map[tx][ty] == 'D')ret = max(ret, dp(tx, ty, st+1)+1); 35 } 36 } 37 return f[x][y] = ret; 38 } 39 40 int main() 41 { 42 // freopen("in.txt", "r", stdin); 43 44 while(scanf("%d%d", &n, &m)!=EOF){ 45 getchar(); 46 for(int i=0; i<n; i++){ 47 for(int j=0; j<m; j++){ 48 scanf("%c", &Map[i][j]); 49 } 50 getchar(); 51 } 52 int ans = 0; 53 memset(f, -1, sizeof f); 54 for(int i=0; i<n; i++){ 55 for(int j=0; j<m; j++){ 56 if(Map[i][j] == 'D'){ 57 ans = max(ans, dp(i, j, 0)); 58 if(ans == INF) break; 59 } 60 } 61 } 62 for(int i=0; i<n; i++){ 63 for(int j=0; j<m; j++){ 64 if(f[i][j]!=-1){ 65 for(int k=0; k<4; k++){ 66 int tx = i+xx[k]; 67 int ty = j+yy[k]; 68 if(tx>=0 && tx<n && ty>=0 && ty<m && Map[i][j]=='A' && Map[tx][ty]=='D'){ 69 if(f[i][j]<=f[tx][ty] && f[i][j]>0){ans = INF;} 70 } 71 if(tx>=0 && tx<n && ty>=0 && ty<m && Map[i][j]=='D' && Map[tx][ty]=='I'){ 72 if(f[i][j]<f[tx][ty] && f[i][j]>0){ans = INF;} 73 } 74 if(tx>=0 && tx<n && ty>=0 && ty<m && Map[i][j]=='I' && Map[tx][ty]=='M'){ 75 if(f[i][j]<f[tx][ty] && f[i][j]>0){ans = INF;} 76 } 77 if(tx>=0 && tx<n && ty>=0 && ty<m && Map[i][j]=='M' && Map[tx][ty]=='A'){ 78 if(f[i][j]<f[tx][ty] && f[i][j]>0){ans = INF;} 79 } 80 } 81 } 82 } 83 } 84 if(ans == 0)printf("Poor Dima! "); 85 else if(ans == INF) printf("Poor Inna! "); 86 else printf("%d ", ans); 87 } 88 return 0; 89 }