2017 EC final J(差分)

题目

题意:有n种扑克牌,每种扑克牌有ai张,每次可以打出3到5张连续的牌作为顺子,问这副牌能不能用顺子全打出来.

思路:又差分序列的性质可知,对于序列a[i],求出差分序列b[i]=a[i]-a[i-1],差分序列前k项和sum[k]=a[k]。题目给出了a[1]……a[n],我们求出差分序列b[1]……b[n],令b[n+1]=0-a[n],那么最后的sum[n+1]=0.我们(条件允许)打出一个顺子(设其出牌的区间为【l,r】,那么b[l]要减一,b[r+1]要加一
)能这样做的条件是b[l]>0,b[r+1]<0且,sum[l]+b[r]>=0, 再结合区间长度必须大于3的要求即可出解,至于区间长度小于5不用管,因为任何一个长度大于5的区间都可以从3 、4 、5凑出来。

#include<cstdio>
using namespace std;
int cas,a[200005],b[200005],t,n;
int main(){
 scanf("%d",&t);
 while(t--){
  scanf("%d",&n);
  for(int i=1;i<=n;i++){
   scanf("%d",&a[i]);
   b[i]=a[i]-a[i-1];
  }
  b[n+1]=0-a[n];
  int f=1,sum=0,p;
  if(b[2]<0||b[3]<0) f=0;
  else{
   for(int i=1;i<=n+1;i++){
    if(b[i]>0) sum+=b[i];
    p=i+3;
    if(p>n+1) break;
    if(b[p]<0) sum+=b[p];
    if(sum<0) break;
   }
   if(sum!=0) f=0;
  }
  if(f)  printf("Case #%d: Yes\n",++cas);
  else  printf("Case #%d: No\n",++cas); 
 }
 return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值