Codeforces Round #220 (Div. 2)
题意:给出如下参数,
n, m, i, j, a, b (1 ≤ n, m ≤ 106; 1 ≤ i ≤ n; 1 ≤ j ≤ m; 1 ≤ a, b ≤ 106).
其中n,m表示有一个n*m的grid,起点在(i, j),问从起点移动到四个拐角(1, m), (n, 1), (n, m), (1, 1)之一,最少
的步数是多少,如果在位置(x,y) 那么可以移动到 (x - a, y - b) (x + a, y - b) (x - a, y + b) (x + a, y + b) 四个
位置之一。
分析:四种情况(走到一个角)处理的方式相同,首先拐角的行坐标和当前位置的行坐标之差必须是a的倍数,纵坐标
之差是b的倍数,其次a加的次数和b加的次数的奇偶性一定相同,然后a,b的范围不能越界,最后步数取a和b加
的次数中大的那一个。
/*************************************** * File Name:220a.cpp * Author:sky0917 * Created Time:2013年12月20日 16:17:25 ***************************************/ #include <map> #include <cmath> #include <queue> #include <string> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int INF = 0x1f1f1f1f; int a, b; int n, m; int cal(int x, int y){ if (x == 0 && y == 0) return 0; if (a > x && a >= n-x) return INF; if (b > y && b >= m-y) return INF; if (x % a != 0 || y % b != 0){ return INF; } if ((x / a) % 2 != (y / b) % 2){ return INF; } return max(x/a, y/b); } int main(){ int x, y; int res; while (scanf("%d %d %d %d %d %d",&n,&m,&x,&y,&a,&b)!=EOF){ res = INF; res = min(res, cal(x-1, y-1)); res = min(res, cal(x-1, m-y)); res = min(res, cal(n-x, y-1)); res = min(res, cal(n-x, m-y)); if (res != INF){ printf("%d\n",res); } else puts("Poor Inna and pony!"); } return 0; }
题意:给出一个长度为n的数字组成的字符串,每次可以对字符串作如下操作:把相邻的两个和为9的数替换成一个9。要求
最后字符串中9的个数最多,假设做多为ma,那么有多少冲改变方式可以使得最终9的个数为ma.
思路: 考虑字符串的一个子串,abcdef满足a+b!=9,b+c=9,c+d=9,d+e=9,e+f!=9那么可以把子串bcde单独拿出来考虑,
它的改变不会影响其他的子串的改变。假设这个子串的长度为m,如果m为偶数,那么变的方式唯一,即变成m/2个9,
如果m为奇数,那么改变的方式为(m+1)/2 ,因为有一个数不参与变化,这个数是隔一个数出现一次的,最后把每个
子串的情况乘起来即可。
/*************************************** * File Name:220b.cpp * Author:sky0917 * Created Time:2013年12月20日 17:55:52 ***************************************/ #include <map> #include <cmath> #include <queue> #include <string> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 100005; char a[maxn]; int main(){ long long res; while (scanf("%s",a)!=EOF){ int len = strlen(a); res = 1; for (int i=0; i<len; i++){ long long tmp = 1; while (i<len-1 && a[i]+a[i+1] - '0' - '0' == 9){ tmp += 1; i++; } if (tmp % 2 == 1){ res *= tmp/2 + 1; } } printf("%I64d\n",res); } return 0; }
题意:给出一个n*m的方格阵,方格阵中只有D,I,M,A,每次只能从按DIMA的顺序走,问最长可以走的单词个数是
多少,如果出现循环,则个数为INF。
分析:d[i][j]表示从(i,j)出发走的最长单词数,dfs即可。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1002; const int INF = 0x1f1f1f1f; int f[8] = {-1, 1, 0, 0, 0, 0, -1, 1}; char g[maxn][maxn]; int d[maxn][maxn]; int v[maxn][maxn]; bool li[333][333]; int n, m; int cnt; int res; bool flag; inline bool ok(int x, int y){ return x>=0 && x<n && y>=0 && y<m; } void dfs(int x, int y){ v[x][y] = cnt; int dp = 0; d[x][y] = INF; for (int i=0; i<4; i++){ int xx = x + f[i]; int yy = y + f[i+4]; if (ok(xx, yy) && li[g[x][y]][g[xx][yy]]){ if (d[xx][yy]){ dp = max(dp, d[xx][yy]); } else{ dfs(xx, yy); dp = max(dp, d[xx][yy]); } } } d[x][y] = dp+1; res = max(res, d[x][y]); } void solve(){ cnt = 0; res = 0; for (int i=0; i<n; i++){ for (int j=0; j<m; j++){ if (!v[i][j] && g[i][j]=='D'){ cnt++; dfs(i, j); } } } if (res > INF){ printf("Poor Inna!\n"); return; } res /= 4; if (res < 1)printf("Poor Dima!\n"); else printf("%d\n",res); } int main(){ li['D']['I'] = li['I']['M'] = li['M']['A'] = li['A']['D'] = true; while (scanf("%d %d",&n,&m)!=EOF){ for (int i=0; i<n; i++){ scanf("%s",g[i]); } solve(); } return 0; }
题意:给出一个有m个数的的数组,a1, a2, ..., am, 表示每次删除的数为第a1,a2..am个数,前提是这个数存在。
有n次操作,每次操作如下:
1 在序列最后加上一个数1,
0 在序列最后加上一个树0,
-1最序列进行一次删除操作。
输出n次操作后的数组。
分析:由于每次只追加一个数,那么删除的次数不可能超过n,删除第ai个数的时候,用二分+树状数组找到删除的位置。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1000005; int n, m; int v[maxn]; int a[maxn]; inline int lowbit(int x){ return (x) & (-x); } void add(int pos, int x){ while (pos <= n){ v[pos] += x; pos += lowbit(pos); } } int getsum(int pos){ int sum = 0; while (pos > 0){ sum += v[pos]; pos -= lowbit(pos); } return sum; } int val[maxn]; int sum[maxn]; void del(int x){ for (int i=0; i<m; i++){ if (getsum(x) < a[i]){ return; } int l = 1, r = x-1, mid; while (l <= r){ mid = (l+r)>>1; int s = getsum(mid); if (s < a[i]) l = mid+1; else r = mid-1; } add(l, -1); } } int main(){ while (scanf("%d %d",&n,&m)!=EOF){ for (int i=0; i<m; i++){ scanf("%d",&a[i]); a[i] -= i; } for (int i=1; i<=n; i++){ scanf("%d",&val[i]); if (val[i] < 0) del(i); else add(i, 1); } sum[0] = 0; for (int i=1; i<=n; i++){ sum[i] = getsum(i); if (sum[i] - sum[i-1] == 1){ printf("%d",val[i]); } } if (sum[n] == 0){ printf("Poor stack!"); } puts(""); } return 0; }

浙公网安备 33010602011771号