【Codeforces Round #353 Div2】个别题的记录

先是Div2的C.Money Transfers:

题意是指 给定N个点围成一个环(意味着1与N点相连接),每个点各有一个权值,每次可以将任意一个点的任意权值移动到左右一个点上,问最短经过多少步能将所有点权值变为0

数据保证所有点权和为0

思路:找出尽可能多的0,使得对整个序列的操作最少,这些0可能是单点可能是段(我们称它为0序列)

对于一个长度为L和为0的段,对它进行全0操作的步数应该是L-1

所以,我们可以记录前缀和A[i] = A[i - 1] + num;

再记录最长能分成的段数maxx[A[i]],这样答案便是:max(maxx[A[1]],maxx[A[2]]...,maxx[A[N]]);

再用n减去max即可。

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <map>
 5 #include <algorithm>
 6 #pragma warning(disable:4996)
 7 using namespace std;
 8 typedef long long LL;
 9 const int maxn = 100000 + 10;
10 map<LL, int>maxx;
11 LL a[maxn];
12 int main(){
13     LL num;
14     int n;
15     while (~scanf("%d", &n)) {
16         int maxxx = 0;
17         a[0] = 0;
18         maxx.clear();
19         for (int i = 1; i <= n; ++i) {
20             scanf("%I64d", &num);
21             a[i] = (a[i - 1] + num);
22             maxxx = max(maxxx, ++maxx[a[i]]);
23         }
24         printf("%d\n", n - maxxx);
25     }
26     return 0;
27 }
View Code

 再是Div2的D.Tree Construction:

题意是依次给出N个数,并按照他的规则建树:

如果当前元素大于前面的某些元素,那么这个元素必须在之前那些元素的右边;同理,小的就在左边

二叉搜索树

问每一个节点的前一个父亲节点是什么

首先就想到了。。当前元素a[i] 的范围 肯定是 :

1.在最前面的某两个数之间

2.小于或大于所有的前面的数

利用set维护这个数组,利用upperbound查找比他大的第一个数,如果找不到,或者已经有左右儿子

那么iter--(显然在两个数之间!!)因为第一个数是根,所以肯定不会出现向下越界的情况

#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
#include <set>
#pragma warning(disable:4996)
using namespace std;
typedef long long LL;
set<int>tree;
map<int, int>lson;
map<int, int>rson;
const int maxn = 100000 + 10;
int n, nd, res[maxn];
void init() {
    tree.clear();
    lson.clear();
    rson.clear();
}
int main() {
    while (cin >> n) {
        init();
        cin >> nd;
        tree.insert(nd);
        for (int i = 1; i < n; ++i) {
            cin >> nd;
            set<int>::iterator  noww = tree.upper_bound(nd);
            if (noww != tree.end() && lson[*noww] == 0) {
                lson[*noww] = nd;
                res[i] = *noww;
            }
            else {
                noww--;
                rson[*noww] = nd;
                res[i] = *noww;
            }
            tree.insert(nd);
        }
        for (int i = 1; i < n; ++i) {
            if (i != 1) cout << " ";
            cout << res[i];
        }
        cout << endl;
    }
    return 0;
}
View Code

 

posted @ 2016-05-24 16:45  mashiro酱  阅读(167)  评论(0)    收藏  举报