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 }
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 }
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 }