2018 “百度之星”程序设计大赛 - 初赛(A)
第二题还算手稳+手快?最后勉强挤进前五百(期间看着自己从两百多掉到494名)
1001 度度熊拼三角 (hdoj 6374)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6374
签到题
题意:给n根木棒 求可以拼出的周长最长的三角形
可以用贪心的思想做 对所有的木棒长度进行排序 取最长的三根进行判断是否可以组成三角形 若不能 舍去最长的一根 每次都选择相邻的三根 for一遍就好
复杂度为O(nlogn)
代码如下
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=1010; int n,ans; int a[maxn]; int cmp(int a,int b){ return a>b; } int check(int x){ if(a[x]+a[x+1]>a[x+2]&&a[x]+a[x+2]>a[x+1]&&a[x+2]+a[x+1]>a[x]) return 0; else return 1; } int main(){ while(scanf("%d",&n)!=EOF){ for(int i=0;i<n;i++){ scanf("%d",&a[i]); } sort(a,a+n,cmp); int flag=0; for(int i=0;i<n;i++){ if(check(i)==0) {ans=a[i]+a[i+1]+a[i+2];flag=1;break;} } if(flag==1) printf("%d\n",ans); else printf("-1\n"); } return 0; }
1002 度度熊学队列 (hdoj 6375)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6375
因为是用stl里的list做的 对我来说也算是个签到题了 几乎就算是个list的板子题了
题意:rt 讲的非常清楚
没想到居然没有卡 stl 从此有了stl的真香警告(突然开始打算好好学stl了)
代码如下
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <list> using namespace std; const int maxn=150010; list<int>lst[maxn]; int n,q,op,u,v,w,val; void read(int &x){ char ch = getchar();x = 0; for (; ch < '0' || ch > '9'; ch = getchar()); for (; ch >='0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0'; } int main(){ while(scanf("%d%d",&n,&q)!=EOF){ for(int i=1;i<=n;i++) lst[i].clear(); while(q--){ read(op); if(op==1){ read(u);read(w);read(val); if(w==0) lst[u].push_front(val); if(w==1) lst[u].push_back(val); } if(op==2){ read(u);read(w); if(lst[u].empty()) {printf("-1\n");} else{ if(w==0) {printf("%d\n",lst[u].front());lst[u].pop_front();} if(w==1) {printf("%d\n",lst[u].back());lst[u].pop_back();} } } if(op==3){ read(u);read(v);read(w); if(w==0) lst[u].splice(lst[u].end(),lst[v]); if(w==1){ lst[v].reverse(); lst[u].splice(lst[u].end(),lst[v]); } } } } return 0; }
1003 度度熊剪纸条 (hdoj 6376)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6376
比赛的时候没有肝出来……orz
题意:给一个长度为n的序列 全部由0 1组成 可以切k刀 切完后的k+1段可以自由拼接(不可翻转)求最终序列中的前缀1的数量
应该要分四种情况 先上男朋友的代码
代码如下
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int maxn=1e5+50; int n,k,cnt,cnt1,ans; int b[4]; char s[maxn]; struct node { int d,w; }kk[maxn]; int cmp(node a,node b){ if(a.d==b.d) return a.w<b.w; else return a.d>b.d; } void work(int k,int tmp){ for(int i=1;i<=cnt;i++){ if(k>=kk[i].w){ tmp+=kk[i].d; k-=kk[i].w; } } ans=max(ans,tmp); } int main(){ while(scanf("%d%d",&n,&k)!=EOF){ scanf("%s",s+1); if(k==0){ ans=0; for(int i=1;i<=n;i++){ if(s[i]=='1') ans++; else break; } printf("%d\n",ans); continue; } int num=0; cnt=cnt1=0; for(int i=1;i<=n;i++){ if(s[i]=='1'){ num++; if(i==n) b[++cnt1]=num; } else if(num!=0){ if(i-1==num) b[++cnt1]=num; else {kk[++cnt].d=num;kk[cnt].w=2;} num=0; } } k++; ans=0; sort(kk+1,kk+1+cnt,cmp); if(cnt1==2){ work(k,0); work(k-1,b[1]); work(k-1,b[2]); work(k-2,b[1]+b[2]); } else if(cnt1==1){ work(k,0); work(k-1,b[1]); } else work(k,0); printf("%d\n",ans); } return 0; }