Bestcoder #36

2015-04-05 22:04:32

总结:这场比较简单... 写了3题。最后一题待补...

 

A:严格按照题意来写,几个注意点:(1)有3种字符。(2)3种字符出现次数一样。(3)三种字符按顺序出现。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <queue>
10 #include <string>
11 #include <iostream>
12 #include <algorithm>
13 using namespace std;
14 
15 #define MEM(a,b) memset(a,b,sizeof(a))
16 #define REP(i,n) for(int i=0;i<(n);++i)
17 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
18 #define getmid(l,r) ((l) + ((r) - (l)) / 2)
19 #define MP(a,b) make_pair(a,b)
20 
21 typedef long long ll;
22 typedef pair<int,int> pii;
23 const int INF = (1 << 30) - 1;
24 
25 char s[1000];
26 int vis[300];
27 
28 int main(){
29     while(scanf("%s",s) != EOF){
30         MEM(vis,0);
31         int len = strlen(s);
32         bool flag = true;
33         vis[s[0]] = 1;
34         for(int i = 1; i < len; ++i){
35             if(s[i] == s[i - 1]){
36                 vis[s[i]]++;
37                 continue;
38             }
39             if(vis[s[i]]){
40                 flag = false;
41                 break;
42             }
43             else vis[s[i]] = 1;
44         }
45         int cnt = 0;
46         int num = 0;
47         for(int i = 0; i < 300; ++i) if(vis[i]){
48             if(cnt == 0) num = vis[i];
49             cnt++;
50             if(vis[i] != num){
51                 flag = false;
52                 break;
53             }
54         }
55         if(flag && cnt == 3){
56             printf("YES\n");
57         }
58         else printf("NO\n");
59     }
60     return 0;
61 }
View Code

 

B:一开始用map秒掉了... 但是看了 看pretest都跑了近3s,所以强行改成了hash... 最后的终测数据竟然比pretest还弱- =、出题人太良心了。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <queue>
10 #include <string>
11 #include <iostream>
12 #include <algorithm>
13 using namespace std;
14 
15 #define MEM(a,b) memset(a,b,sizeof(a))
16 #define REP(i,n) for(int i=0;i<(n);++i)
17 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
18 #define getmid(l,r) ((l) + ((r) - (l)) / 2)
19 #define MP(a,b) make_pair(a,b)
20 #define maxn 1000009
21 #define mod 10000009
22 
23 typedef long long ll;
24 typedef pair<int,int> pii;
25 const int INF = (1 << 30) - 1;
26 
27 int head[mod + 10],nex[maxn],a[maxn];
28 int point[maxn],now=0,sum[maxn];
29 int cnt[maxn];
30 int n,m;
31 
32 void Add(int x,int y){
33     nex[++now] = head[x];
34     point[now] = y;
35     cnt[now] = 1;
36     head[x] = now;
37 }
38 
39 void Insert(int x){
40     int u = abs(x % mod);
41     for(int i=head[u];i;i=nex[i]) if(point[i]==x){
42         cnt[i]++;
43         return;
44     }
45     Add(u,x);
46 }
47 
48 int Find(int x){
49     int u = abs(x % mod);
50     for(int i=head[u];i;i=nex[i]) if(point[i]==x){
51         int cur = cnt[i];
52         cnt[i] = 0;
53         return cur;
54     }
55     return 0;
56 }
57 
58 int Read(){
59     int x=0;char ch=getchar();
60     while(ch<'0'||ch>'9') ch=getchar();
61     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
62     return x;
63 }
64 
65 int main(){
66     int a;
67     while(scanf("%d%d",&n,&m) != EOF){
68         now = 0;
69         MEM(head,0);
70         MEM(cnt,0);
71         for(int i = 1; i <= n; ++i){
72             a = Read();
73             Insert(a);
74         }
75         for(int i = 1; i <= m; ++i){
76             a = Read();
77             printf("%d\n",Find(a));
78         }
79     }
80     return 0;
81 }
View Code

 

C:比较明显的离线+并查集... 在初始化上卡了半小时(囧)... 不过A完之后发现并查集是多余的。。

  首先将查询降序排序,树高升序排序。首先考虑最大询问,此时砍掉的树最多,将没被砍掉的数标记一下(vis[i] = 1),然后逐个考虑询问。

  对于每一个询问,都可能有新的树 “长” 出来,由于树高已经排好序了,这部分很容易处理,对于新树,只要考虑其左右两边是否已经有树。

  如果左右两边均没有数,那么块数+1。如果两边都有树,那么块数-1。否则块数不变。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <queue>
10 #include <string>
11 #include <iostream>
12 #include <algorithm>
13 using namespace std;
14 
15 #define MEM(a,b) memset(a,b,sizeof(a))
16 #define REP(i,n) for(int i=0;i<(n);++i)
17 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
18 #define getmid(l,r) ((l) + ((r) - (l)) / 2)
19 #define MP(a,b) make_pair(a,b)
20 
21 typedef long long ll;
22 typedef pair<int,int> pii;
23 const int INF = (1 << 30) - 1;
24 const int MAXN = 50010;
25 
26 int N,Q;
27 int vis[MAXN];
28 int now;
29 int ans[MAXN];
30 
31 struct node{
32     int h,id;
33 }nd[MAXN];
34 
35 struct query{
36     int q,id;
37 }q[MAXN];
38 
39 bool cmp(query a,query b){
40     return a.q > b.q;
41 }
42 
43 bool cmp1(node a,node b){
44     return a.h < b.h;
45 }
46 
47 int main(){
48     while(scanf("%d%d",&N,&Q) != EOF){
49         now = 0;
50         MEM(vis,0);
51         for(int i = 1; i <= N; ++i){
52             scanf("%d",&nd[i].h);
53             nd[i].id = i;
54         }
55         for(int i = 1; i <= Q; ++i){
56             scanf("%d",&q[i].q);
57             q[i].id = i;
58         }
59         sort(q + 1,q + Q + 1,cmp);
60         sort(nd + 1,nd + N + 1,cmp1);
61         //init
62         int pos;
63         for(pos = N; pos >= 1; --pos){
64             if(nd[pos].h > q[1].q) vis[nd[pos].id] = 1;
65             else break;
66         }
67         for(int i = 1; i <= N; ++i) if(vis[i] && !vis[i - 1]) now++;
68         ans[q[1].id] = now;
69         for(int i = 2; i <= Q; ++i){
70             for(; pos >= 1; --pos){
71                 if(nd[pos].h <= q[i].q) break;
72                 int cur = nd[pos].id;
73                 int cnt = vis[cur - 1] + vis[cur + 1];
74                 vis[cur] = 1;
75                 if(cnt == 2) now--;
76                 if(cnt == 0) now++;
77             }
78             ans[q[i].id] = now;
79         }
80         for(int i = 1; i <= Q; ++i)
81             printf("%d\n",ans[i]);
82     }
83     return 0;
84 }
View Code

 

转载于:https://www.cnblogs.com/naturepengchen/articles/4394909.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值