Codeforces Round #220 (Div. 2)

A. Inna and Pink Pony

题意:给出如下参数,

         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;
}
View Code

 

B.Inna and Nine

题意:给出一个长度为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;
}
View Code

 

C.Inna and Dima

题意:给出一个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;
}
View Code

 

D. Inna and Sequence

题意:给出一个有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;
}
View Code

 

 

posted @ 2013-12-23 23:20  sky0917  阅读(358)  评论(0)    收藏  举报