Codeforces Round #335 div2

来源:互联网 发布:日亚海淘 知乎 编辑:程序博客网 时间:2024/05/21 19:32

Codeforces Round #335 div2
A:
题意:
三个初始状态(a,b,c)是否能经过一种变换得到一个三元组(a’,b’,c’)满足a’>=x,b’>=y,c’>=z。
变换方法是同一维度的值减少2,可以使另一个维度增加1.比如(x,y,z) -> (x-2,y+1,z)
思路:
把三个维度的差值算出来,排成一个数组。然后看每个正数的一半的和是否大于负数的绝对值即可。
源码:

#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>#include <iostream>using namespace std;int temp[5];int main(){    int a, b, c;    int x, y, z;    while(scanf("%d%d%d%d%d%d", &a, &b, &c, &x, &y, &z) != EOF){        temp[0] = a - x;        temp[1] = b - y;        temp[2] = c - z;        sort(temp, temp + 3);        int ok = 1;        int a, b;        a = 0, b = 0;        for(int i = 0 ; i < 3 ; i++){            if(temp[i] >= 0)    a += temp[i] / 2;            else    b += -temp[i];        }        if(a >= b)  printf("YES\n");        else    printf("NO\n");    }    return 0;}

B:
题意:
给出一个地图(<= 500 * 500),一个人的初始点。
现在给他一串指令,它会按照指令进行上下左右的移动。如果由于边界问题移动非法则不移动。
现在知道可以在一个点放置炸弹,人走到炸弹就会爆炸。如果所有步数走完没碰到炸弹也会爆炸。
问一个人刚好执行0,1,2…k条指令爆炸的情况中,合法的炸弹放置方案由多少个。
思路:
读题题。暴力走一遍即可,除了执行完最后一条指令不碰到炸弹也会爆炸外,其余点的合法炸弹数非0即1。0的情况即此点之前走过。
源码:

#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <iostream>#include <string>using namespace std;char op[100000 + 5];int ans[100000 + 5];int vis[500 + 5][500 + 5];int n, m;void change(char c, int &x, int &y){    int tx, ty;    tx = x, ty = y;    if(c == 'L')    y--;    if(c == 'R')    y++;    if(c == 'U')    x--;    if(c == 'D')    x++;    if(x < 1 || x > n || y < 1 || y > m)    x = tx, y = ty;}int main(){    int sx, sy;    while(scanf("%d%d%d%d", &n, &m, &sx, &sy) != EOF){        memset(vis, 0, sizeof(vis));        scanf("%s", op);        int len = strlen(op);        int cnt = 1;        ans[0] = 1;        vis[sx][sy] = 1;        for(int i = 0 ; i < len ; i++){            change(op[i], sx, sy);//            printf("sx = %d, sy = %d\n", sx, sy);            if(vis[sx][sy]) ans[i + 1] = 0;            else    cnt++, vis[sx][sy] = 1, ans[i + 1] = 1;        }        if(ans[len] == 1)   ans[len] = n * m - cnt + 1;        else    ans[len] = n * m - cnt;        for(int i = 0 ; i <= len ; i++){            printf("%d", ans[i]);            if(i == len)    printf("\n");            else    printf(" ");        }    }    return 0;}

C:
题意:
给一个1-n的排列(n<=100000)。现在有操作每次从排列中取出一个数放在排头或者排尾。问操作次数最少使得排列成为一个上升子序列。
思路:
因为拿的顺序随意,所以按照顺序把一个个不合法的数按照大小拿到队首或队尾即可,即一个数最多操作一次。
关键是哪些数是不用移动的。然后就试出来这个性质:对于序列中最长的步长为1的上升子序列,可以知道这些数都不移动时最优。因为序列是最长的,而且可以通过把中间“多余”的元素放到队首或者队尾,所以此时最优。
源码:

#include <cstdio>#include <cmath>#include <cstring>#include <cstdlib>#include <string>#include <algorithm>#include <iostream>using namespace std;const int MAXN = 1e5 + 5;int a[MAXN];int id[MAXN];int main(){    int n;    while(scanf("%d", &n) != EOF){        for(int i = 1 ; i <= n ; i++){            scanf("%d", a + i);            id[a[i]] = i;        }        int ans = 1;        int re = 1;        for(int i = 2 ; i <= n ; i++){            if(id[i] > id[i - 1])   re++;            else{                ans = max(ans, re);                re = 1;            }        }        ans = max(ans, re);        printf("%d\n", n - ans);    }    return 0;}

D: http://blog.csdn.net/beihai2013/article/details/50257067

0 0
原创粉丝点击