Straight Master Gym-101775J (思維+差分)
阿新 • • 發佈:2018-10-05
mas 差分 esp turn open sum ++i online master
題意:給出N種類的數量,求是否可以把N種牌按3-5張連續的順子打出,順子必須連續.
分析:相當於把這個序列分成若幹長度為[3,5]的區間,當然其實分成若幹段大於3的區間即可.因為大於5的區間又可以分拆成若幹段長度為[3,5]的區間.
令\(b[i] = a[i] - a[i-1]\), 則\(b[i] >0\) 表示有\(b[i]\)段區間以此為起點, \(b[i] < 0\)表示有\(|b[i]|\)段區間以\(i-1\)為終點. 那麽對於每個區間的起點i,必須在i+3開始的位置一直向後尋找終點,且起點和終點必須數量相等,若不相等則不能打出順子.
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int MAXN = 2e5+5; LL a[MAXN], b[MAXN]; int N; bool check() { LL sum = 0; if(b[2] <0 || b[3]<0) return false; for(int i=1;i<=N+1;++i){ int p = i + 3; if(b[i] > 0) sum += b[i]; if(p > N+1) break; if(b[p]<0 ){ sum += b[p]; b[p] = 0; } if(sum<0) break; } if(sum !=0) return false; return true; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif int T,cas=1; scanf("%d",&T); while(T--){ scanf("%d", &N); for(int i=1;i<=N;++i){ scanf("%lld", &a[i]); b[i] = a[i] - a[i-1]; } b[N+1] = -a[N]; printf("Case #%d: ",cas++); if(check()) printf("Yes\n"); else printf("No\n"); } return 0; }
Straight Master Gym-101775J (思維+差分)