模拟练1

00FF0294打败我的不是天真,是天真热。。。

补一下最近做的模拟题:

hdu5532Almost Sorted Array

题意:一个含n个数的序列,能否从中只删除一个数,使得剩余序列为有序序列。(不递增或不递减序列)

题解:分别判断删除一个数后是否为不递增或不递减序列,同时还需判断删除数的前后两项是否满足序列关系。例如,判断是否为不递减序列时,若a[i]<a[i-1],对于序列1 2 5 3 4 7,若删除i项3,比较其前后两项发现不符合序列关系,则考虑删除i-1项5,再比较5的前后两项判断是否符合序列关系。

 

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int N=100005;
 5 int a[N],n;
 6 int jud1(){//判断是否为不递减序列
 7     int i,f=0;
 8     a[0]=0,a[n+1]=N;
 9     for(i=2;i<=n;++i){
10         if(a[i]<a[i-1]){
11             if(f)return 0;
12             f=1;
13             if(a[i+1]>=a[i-1]||a[i]>=a[i-2])continue;
14             else return 0;
15         }
16     }
17     return 1;
18 }
19 int jud2(){//判断是否为不递增序列
20     int i,f=0;
21     a[0]=N,a[n+1]=0;
22     for(i=2;i<=n;++i){
23         if(a[i]>a[i-1]){
24             if(f)return 0;
25             f=1;
26             if(a[i+1]<=a[i-1]||a[i]<=a[i-2])continue;
27             else return 0;
28         }
29     }
30     return 1;
31 }
32 int main(){
33     int t,i;
34     scanf("%d",&t);
35     while(t--){
36         scanf("%d",&n);
37         for(i=1;i<=n;++i)scanf("%d",&a[i]);
38         if(jud1()||jud2())puts("YES");
39         else puts("NO");
40     }
41     return 0;
42 }
Code

 

 

hdu5583Kingdom of Black and White

题意:给出一串01字符串,例如:0011000

                                            2  2  3   =>2*2+2*2+3*3

最多只能改变一个数字(0->1或1->0),使得最后平方和最大

题解:暴力枚举求最大值。枚举 第i块字符数+1与第i+1块字符数-1 和 第i块字符数-1与第i+1块字符数+1的情况,注意第i+1块只有一个字符(第i,i+1,i+2会合成一块)与第i块只有一个字符时(第i-1,i,i+1会合成一块)的情况。

 

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int N=100005;
 5 typedef long long ll;
 6 ll s[N];
 7 char a[N];
 8 int main(){
 9     int t,i,j,c=1;
10     ll ans,ma,k;
11     scanf("%d",&t);
12     while(t--){
13         scanf("%s",a);
14         for(s[0]=0,ans=0,i=1,j=1,k=1;a[i]!='\0';++i)
15             if(a[i]!=a[i-1]){s[j++]=k;ans+=k*k;k=1;}
16             else k++;
17         s[j++]=k;ans+=k*k;
18         s[j++]=0;
19         for(ma=ans,i=1;i<j-2;++i){
20             if(s[i+1]==1)ma=max(ma,ans-s[i]*s[i]-1-s[i+2]*s[i+2]+(s[i]+1+s[i+2])*(s[i]+1+s[i+2]));
21             else ma=max(ma,ans-s[i]*s[i]-s[i+1]*s[i+1]+(s[i]+1)*(s[i]+1)+(s[i+1]-1)*(s[i+1]-1));
22             if(s[i]==1)ma=max(ma,ans-s[i-1]*s[i-1]-1-s[i+1]*s[i+1]+(s[i-1]+1+s[i+1])*(s[i-1]+1+s[i+1]));
23             else ma=max(ma,ans-s[i]*s[i]-s[i+1]*s[i+1]+(s[i]-1)*(s[i]-1)+(s[i+1]+1)*(s[i+1]+1));
24         }
25         printf("Case #%d: %lld\n",c++,ma);
26     }
27     return 0;
28 }
Code

 

 

hdu5461Largest Point

题意:给出n个数,从中取出2个数ti,tj(ti≠tj),使得015961C5最大。

题解:用两个数组分别维护a*015A9949和 b*tj的最大值与次大值,同时记录下标,最后判断下标从而求出最大值。

 

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 typedef long long ll;
 5 const ll inf=0x3f3f3f3f3f3f3f3f;
 6 ll a[2],b[2];
 7 int n,ida[2],idb[2];
 8 void update(ll w,int i,ll *s,int *id){
 9     if(w>s[1]){swap(s[1],w);swap(id[1],i);}
10     if(s[1]>s[0]){swap(s[1],s[0]);swap(id[1],id[0]);}
11 }
12 ll F(){
13     if(ida[0]==idb[0])return max(a[0]+b[1],a[1]+b[0]);
14     return a[0]+b[0];
15 }
16 int main(){
17     int i,x,t,A,B,k=1;
18     scanf("%d",&t);
19     while(t--){
20         a[0]=a[1]=b[0]=b[1]=-inf;
21         scanf("%d%d%d",&n,&A,&B);
22         for(i=0;i<n;++i){
23             scanf("%d",&x);
24             update(1LL*A*x*x,i,a,ida);
25             update((ll)B*x,i,b,idb);
26         }
27         printf("Case #%d: %lld\n",k++,F());
28     }
29     return 0;
30 }
Code

 

 

 

 

hdu5573Binary Tree

题意:给出n和k,用k层的完全二叉树,从根节点走到叶子节点,将走过的k个数加减组成n,输出结果

题解:由数据范围n<=01571116想到用二叉树最左边一列k个数,二进制思想构造即可(1表示加,0表示减)。最左列和为sum=01571116-1,设需要减去的值d=sum-n,只需将d/2(如果二进制该位为0,相对于sum表示减去两倍该位代表的值)二进制中的1变为0即可。注意若n为偶数,差d为奇数,则要先将d加一,即最后一步走右节点。

 

 1 #include<cstdio>
 2 int main(){
 3     int i,t,j,k;
 4     long long n,d;
 5     scanf("%d",&t);
 6     for(i=1;i<=t;++i){
 7         scanf("%lld%d",&n,&k);
 8         printf("Case #%d:\n",i);
 9         d=(1LL<<k)-1;
10         d-=n;
11         if(n%2==0)d++;
12         d/=2;
13         for(j=0;j<k-1;++j){
14             printf("%lld ",(1LL<<j));
15             if((1LL<<j)&d)printf("-\n");
16             else printf("+\n");
17         }
18         printf("%lld +\n",n&1?1LL<<(k-1):(1LL<<(k-1))+1);
19     }
20     return 0;
21 }
Code

 

 

 

 

Codeforces526C- Om Nom and Candies

题意:有两种数量不限的糖,每种糖都有两个属性:重 w kg,欢乐值 h 。最多只能吃 C kg,求能得到的最高欢乐值。

题解:分两种情况:

①若max(wa,wb)>0133FCDA,假设b糖质量更大,则枚举b糖的个数,且b糖最多只能选0133FCDA个。

②若①不成立,则比较两糖的性价比

假设:01394E54 即wb*ha < wa*hb,说明吃wb个a糖没有吃wa个b糖划算,所以枚举性价比低的a糖,且其最多只能选的数量小于wb个(因为超过wb个则不如换成b糖)。这样两种情况的复杂度都为O(0133FCDA

 

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 using namespace std;
 6 int main(){
 7     long long c,ha,hb,wa,wb,ans=0;
 8     int i;
 9     scanf("%I64d%I64d%I64d%I64d%I64d",&c,&ha,&hb,&wa,&wb);
10     if(wa>wb){swap(wa,wb);swap(ha,hb);}
11     if(wb>=sqrt(c)){
12         for(i=0;i<=c/wb;++i)
13             ans=max(ans,i*hb+(c-i*wb)/wa*ha);
14     }
15     else{
16         if(ha*1./wa > (hb*1./wb)){swap(wa,wb);swap(ha,hb);}
17         for(i=0;i<wb;++i)ans=max(ans,i*ha+(c-i*wa)/wb*hb);
18     }
19     printf("%I64d\n",ans);
20     return 0;
21 }
Code

 

【如有错误,敬请指正,欢迎交流】

posted @ 2016-07-28 19:37  GraceSkyer  阅读(280)  评论(0编辑  收藏  举报

~~~~~~ACM大牛语录,激励一下~~~~~~

为了世界的和平,为了女生的安全,我拼命做题,做题,做题!

用最短的时间,刷最多的题!

给我一滴泪,我就看到了你全部的海洋!

seize the hour, seize the day.

人生难免有无奈,幸福走远了,或是感叹幸福来迟了.其实我一直相信,无论手中的幸福是多么微不足道的感觉,我会把握住那每一分,每一秒,当幸福依旧像那百鸟般飞逝,终究无法掌握时,我会感谢它,曾经降临过!

A自己的题,让别人郁闷去吧

WA肠中过,AC心中留 TLE耳边过,AC特别牛

天然的悲苦和伤逝,过去有过,以后还会有

^*^一步一步往上爬^*^

AC就像练级,比赛就像PK. 练级不如PK好玩

其实,世上本没有ACM,AC的人多了,也便有了!

AC无止尽~ Seek you forever~

找呀找呀找水题,找到一个AC一个呀!

AC是检验程序的唯一标准。

真的猛士,敢于直面惨淡的人生,敢于正视淋漓的鲜血……