Codeforces Round #225 (Div. 2)

A. Coder

题意:给出一个n*n的grid 现在要在上面尽量多的放棋子,问最多能放多少个,满足不存在任意两个棋子相邻。

分析:n是奇数:能放n*n/2  

         n是偶数:能放(n*n+1)/2

Codeforces Round #225 (Div. 2)
/****************************************
* File Name: 225a.cpp
* Author: sky0917
* Created Time: 2014年01月20日 23:28:39
****************************************/
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1000005;

int a[maxn];
int main(){
    int n;  
    while (scanf("%d",&n)!=EOF){
        if (n % 2 == 0){
            printf("%d\n",n*n/2);
            int cnt = 0;
            for (int i=0; i<n; i++){
                cnt++;
                for (int j=0; j<n; j++){
                    if ((j+cnt)%2==0){
                        putchar(C);
                    }   
                    else putchar(.);
                }
                puts("");
            }
        }
        else{
            printf("%d\n",(n*n+1)/2);
            int cnt = 0;
            for (int i=0; i<n; i++){
                for (int j=0; j<n; j++){
                    if ((j+cnt)%2==0){
                        putchar(C);
                    }   
                    else putchar(.);
                }
                cnt++;
                puts("");
            }   
        }   
    }
    return 0;
}
View Code

 

B. Multitasking

题意:有n个数组,每个数组有m个数,现在最多能进行m*(m-1)/2次操作,每次给出i,j,如果然后每个数组中如果

         a[i] < a[j] 则交换之,否则不交换,输出操作序列,和次数。

分析:直接模拟。

Codeforces Round #225 (Div. 2)
/****************************************
* File Name: 225b.cpp
* Author: sky0917
* Created Time: 2014年01月20日 23:48:05
****************************************/
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 102;

int g[maxn][maxn];
int r[maxn];
struct node{
    int ll, rr;
}q[maxn * maxn];
int main(){
    int n, m, k;
    while (scanf("%d %d %d",&n,&m,&k)!=EOF){
        int a, b;
        for (int i=0; i<n; i++){
            for (int j=0; j<m; j++){
                scanf("%d",&r[j]);
            }
            for (int j=0; j<m; j++){
                for (int l=j+1; l<m; l++){
                    if (k == 0 && r[j] > r[l]){
                        g[j][l] = 1;
                    }
                    if (k == 1 && r[j] < r[l]){
                        g[l][j] = 1;
                    }
                }
            }   
        }
        int tp = 0;
        for (int i=0; i<m; i++){
            for (int j=0; j<m; j++){
                if (g[i][j]){
                    q[tp].ll = i;
                    q[tp++].rr = j;
                }
            }
        }   
        printf("%d\n",tp);
        for (int i=0; i<tp; i++){
            printf("%d %d\n",q[i].ll+1,q[i].rr+1);
        }
    }   
    return 0;
}
View Code

 

C. Milking cows

题意:有n头牛,他们要么向左看,要么向右看,现在要给每个牛挤一次奶,被挤奶的牛的两侧,所有看到它的牛的产奶量

        都会减去 1,现在要找到一个挤奶序列,使得总的减少的奶最少,被挤奶的奶牛不会在减少奶。

分析:可以按照能看到别的牛的数量从小到大一次把牛加进来,相当于是把过程倒过来。

          还看到一种思路:从左向右遍历,如果是1 就tmp++, 如果是0 就res+=tmp 最后输出res。

Codeforces Round #225 (Div. 2)
/****************************************
* File Name: 255c.cpp
* Author: sky0917
* Created Time: 2014年01月21日  0:09:40
****************************************/
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 200002;

int n;
long long a[maxn];
inline long long lowbit(int x){
    return (x) & (-x);
}
void add(int pos, long long x){
    while (pos <= n){
        a[pos] += x;
        pos += lowbit(pos);
    }
}
long long getsum(int pos){
    long long sum = 0;
    while (pos > 0){
        sum += a[pos];
        pos -= lowbit(pos);
    }
    return sum;
}

struct node{
    int p;
    int di;
    long long ti;
}q[maxn];
bool cmp(node na, node nb){
    return na.ti < nb.ti;
}
int main(){
    int va;
    while (scanf("%d",&n)!=EOF){
        for (int i=1; i<=n; i++){
            scanf("%d",&va);
            q[i-1].di = va;
            q[i-1].p = i;
            if (va == 0)
                q[i-1].ti = (long long)i-1;
            else 
                q[i-1].ti = (long long)n-i;
        }

        sort(q, q+n, cmp);
        memset(a, 0, sizeof(a));

        long long res = 0;

        for (int i=0; i<n; i++){
            res += getsum(q[i].p);
            if (q[i].di == 0){
                add(1, 1);
                add(q[i].p, -1);
            }
            else{
                add(q[i].p+1, 1);
            }
        }
        printf("%I64d\n",res);
    }
    return 0;
}
View Code

 

E. Propagating tree

题意:有一个有n个节点的树,每个节点都有一个初始的权值,有m次操作,每次操作有两种:

         1 p v   把 p 节点权值+v,把p的孩子-v,把p的孩子的孩子+p,依次类推。

         2 p      输出p节点的权值。

分析:每次进行1操作的时候:

          +v的节点距离根节点的距离和 p 节点到根节点的距离具有相同的奇偶性

          - v的节点则相反。

          可以先深搜一次,记录每个节点的时间戳ti, 如果遍历完它的所有后代节点之后的时间戳为tj,

          那么这个节点能影响到的范围就是时间戳中[ti, tj]这些节点。

          可以建立一个二维树状数组tr[2][maxn]

          tr[0][i] 记录距离根节点距离为奇数的节点序列,

          tr[1][i] 记录距离根节点距离为偶数的节点序列。

          当 1 p v的时候:

                就把区间tr[dp[p]][l[p]] 到 tr[dp[p]][r[p]] 这段区间都+v            (dp[p] = 0 表示距离为奇数,=1为偶数)

                就把区间tr[dp[p]^1][l[p]] 到 tr[dp[p]^1][r[p]] 这段区间都-v

         当 2 p 的时候:

                输出 tr[dp[p]][l[p]] 的值。

Codeforces Round #225 (Div. 2)
/****************************************
* File Name: 225e.cpp
* Author: sky0917
* Created Time: 2014年01月21日  0:51:40
****************************************/
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 200005;

int n, m;
int tr[2][maxn];
inline int lowbit(int x){
    return (x) & (-x);
}
void add(int pos, int xu, int va){
    while (pos <= n){
        tr[xu][pos] += va;
        pos += lowbit(pos);
    }   
}
int getsum(int xu, int pos){
    int s = 0;
    while (pos > 0){
        s += tr[xu][pos];
        pos -= lowbit(pos);
    }
    return s;
}
int a[maxn];
struct node{
    int to, next;
}e[maxn*2+1];
int tot;
int head[maxn];
void addedge(int s, int t){
    e[tot].to = t;
    e[tot].next = head[s];
    head[s] = tot++;
}
int v[maxn];

int l[maxn];
int r[maxn];
int ti;
int dp[maxn];
void dfs(int u){

    l[u] = ti++;    
    v[u] = 1;
    for (int i=head[u]; i; i=e[i].next){
        int k = e[i].to;
        if (!v[k]){
            dp[k] = (dp[u]+1)%2;
            dfs(k);
        }
    }   
    r[u] = ti-1;
}

int main(){
    while (scanf("%d %d",&n,&m)!=EOF){
        tot = 1;
        for (int i=1; i<=n; i++){
            scanf("%d",&a[i]);      
        }
        int ss, tt;
        for (int i=1; i<n; i++){
            scanf("%d %d",&ss,&tt);
            addedge(ss, tt);
            addedge(tt, ss);
        }       

        ti = 1;
        dp[1] = 0;
        dfs(1);     
        for (int i=1; i<=n; i++){
            add(l[i], dp[i], a[i]); 
            add(l[i]+1, dp[i], -a[i]);
        }

        int op;
        int x, y;
        while (m--){
            scanf("%d",&op);
            if (op == 1){
                scanf("%d %d",&x,&y);           
                add(l[x], dp[x], y);
                add(r[x]+1, dp[x], -y);
                add(l[x], (dp[x]+1)%2, -y);
                add(r[x]+1, (dp[x]+1)%2, y);
            }
            else{
                scanf("%d",&x); 
                int res = getsum(dp[x], l[x]);
                printf("%d\n",res);
            }
        }           
    }
    return 0;
}
View Code

Codeforces Round #225 (Div. 2)

上一篇:HDU 2046 骨牌铺方格


下一篇:photoshop 鼠绘逼真的耳朵