CFGym 100198C (Strange Counter)

题意:定义一个新的二进制表达式,即在原来基础上把最大权值修改为2。其次,我们每加一个2^k保证改变数字不超过4次。给定最长数字长度,现在你需模拟这个过程。

思路:不超过4次,说明我们需要维护这个数字列连续为2的不超过3(高位除外),怎么制定策略呢?,我们可以制定这样的策略:保证两个2之间至少有一个0,因为只有这样,才能在4步内维护这样的结构。我们记录每个2和0的位置,那我们位置p填加时总是保证每个2间有个0。一直维护即可,具体做法参考代码吧。

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e4 + 5;
 4 
 5 int b[maxn];
 6 set<int> p0, p2;
 7 set<int>::iterator it, it1;
 8 
 9 void update(int p,int val) {
10     if(b[p]==0) p0.erase(p);
11     if(b[p]==2) p2.erase(p);
12     b[p] += val;
13     printf("  %d %d", p, b[p]);
14     if(b[p]==0) p0.insert(p);
15     if(b[p]==2) p2.insert(p);
16 }
17 
18 int main() {
19     freopen("counter.in","r",stdin);
20     freopen("counter.out","w",stdout);
21     int n, m;
22     cin >> n >> m;
23     memset(b,0,sizeof(b));
24     p0.clear();
25     p2.clear();
26     for(int i=0;i<n+5;i++)
27         b[i]=0, p0.insert(i);
28     p2.insert(maxn);//记住用upper_bound一定要添加一个不会出现的最大数,否则返回值很诡异 
29     while(m--) {
30         int x;
31         scanf("%d", &x);
32         it = p2.upper_bound(x); //位置x后出现的第一个2 的位置 
33         it1 = p0.upper_bound(*it);  
34         it1 --;// 2前面第一个0的位置 
35         if(x >= *it1) {
36             printf("3");//完全可预估我们所要花的步数 
37             update(*it, -2);
38             update(*it+1, 1);
39             update(x, 1);
40             puts("");
41         } else if(b[x]>0) {
42             printf("2");
43             update(x, -1);
44             update(x+1, 1);
45             puts("");
46         } else {
47             printf("1");
48             update(x, 1);
49             puts("");
50         }
51     }
52     return 0;
53 }

 

posted @ 2017-10-06 09:58  UtopioSPH  阅读(312)  评论(0编辑  收藏  举报