BestCoder Round #20 部分题解(A,B,C)(hdu5123,5124,5125)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
who is the best?
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Each test case begins with an integer N,indicating the number of person.
Next N lines contains an integer ai(1≤ai≤N.
题意:求出现次数最多的数,若有多个数,则输出最小的一个
水题,随便搞
1 #include<iostream> 2 #include <cstring> 3 using namespace std; 4 int a[1010]; 5 int main() 6 { 7 ios::sync_with_stdio(false); 8 int t; 9 cin>>t; 10 int n; 11 memset(a,0,sizeof(a)); 12 while(t--) 13 { 14 int n; 15 cin>>n; 16 int k; 17 int maxx=1; 18 memset(a,0,sizeof(a)); 19 int ans=1; 20 for(int i=0;i<n;i++) 21 { 22 cin>>k; 23 a[k]++; 24 if(a[k]>=maxx) 25 { 26 if(a[k]==maxx) 27 { 28 ans=min(ans,k); 29 } 30 else 31 { 32 ans=k; 33 } 34 maxx=a[k]; 35 } 36 } 37 cout<<ans<<endl; 38 } 39 return 0; 40 }
lines
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Each test case begins with an integer N,indicating the number of lines.
Next N lines contains two integers X and Y,describing a line.
题意:有n条线段,求被覆盖到次数最多的点的次数
分析:
1.可以转化成求前缀和最大的问题:将区间改成左闭右开(即右端点加1),排序,从左往右遍历,若为左端点则加一,右端点则减一。
2.线段树,离散化一下,然后区间更新,单点查询。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cstdio> 6 using namespace std; 7 typedef pair<int,int> PII; 8 PII a[200010]; 9 int main() 10 { 11 ios::sync_with_stdio(false); 12 int t; 13 //freopen("in.in","r",stdin); 14 scanf("%d",&t); 15 while(t--) 16 { 17 int n; 18 scanf("%d",&n); 19 n=n*2; 20 for(int i=0;i<n;i++) 21 { 22 scanf("%d",&a[i].first); 23 a[i].second=1; 24 scanf("%d",&a[++i].first); 25 a[i].first++; 26 a[i].second=-1; 27 } 28 sort(a,a+n); 29 int ans=0; 30 int k=0; 31 for(int i=0;i<n;i++) 32 { 33 k=k+a[i].second; 34 ans=max(k,ans); 35 } 36 printf("%d\n",ans); 37 } 38 }
magic balls
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Each test case begins with two integer N and M,indicating the number of people and the number of the wizard’s energy. Next N lines contains two integer ai and bi(1≤ai,bi≤109),indicating the balls’ volume.
题意:有两组数a,b,另外最多可以对其做m次操作——即swap(a[i],b[i]),问在此情况下a数组最大的LIS长度是多少?
分析:先将数据离散化,然后用m+1个树状数组或者线段树来维护在还剩余j次操作之后到第i个数时的最大的LIS长度。
sad,这道题我用了线段树来维护RMQ,一直TLE,最后在参考了邝巨巨的情况下才过了的。
^_^通过这道题目知道了如何运用树状数组来维护RMQ,之前只会用线段树搞搞。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 using namespace std; 6 struct BIT 7 { 8 int bit[2010]; 9 int n; 10 int init(int size) 11 { 12 n=size; 13 for(int i=0;i<n;i++)bit[i]=0; 14 } 15 int query(int i) 16 { 17 int s=0; 18 while(i>0) 19 { 20 s=max(s,bit[i]); 21 i-=i&-i; 22 } 23 return s; 24 } 25 int update(int i,int x) 26 { 27 while(i<=n) 28 { 29 bit[i]=max(x,bit[i]); 30 i+=i&-i; 31 } 32 } 33 }bt[1010]; 34 int a[1010],b[1010],c[2010]; 35 int main() 36 { 37 //ios::sync_with_stdio(false); 38 int t; 39 //freopen("in.in","r",stdin); 40 scanf("%d",&t); 41 while(t--) 42 { 43 int n,m; 44 scanf("%d%d",&n,&m); 45 int cnt=0; 46 for(int i=0;i<n;i++) 47 { 48 scanf("%d%d",&a[i],&b[i]); 49 c[++cnt]=a[i]; 50 c[++cnt]=b[i]; 51 } 52 sort(c+1,c+cnt+1); 53 cnt=unique(c+1,c+cnt+1)-c-1; 54 for(int i=0;i<n;i++) 55 { 56 a[i]=lower_bound(c+1,c+cnt+1,a[i])-c; 57 b[i]=lower_bound(c+1,c+cnt+1,b[i])-c; 58 } 59 int ans=0; 60 for(int i=0;i<=m;i++)bt[i].init(cnt); 61 for(int i=0;i<n;i++) 62 { 63 for(int j=0;j<=m;j++) 64 { 65 int x=bt[j].query(a[i]-1)+1; 66 bt[j].update(a[i],x); 67 ans=max(ans,x); 68 if(j<m) 69 { 70 x=bt[j+1].query(b[i]-1)+1; 71 bt[j].update(b[i],x); 72 ans=max(ans,x); 73 } 74 } 75 } 76 cout<<ans<<endl; 77 78 } 79 80 return 0; 81 }
D题
目前还不会,不会cdq分治。。。