Straight Master (貪心)
題目如下:
A straight is a poker hand containing five cards of sequential rank, not necessarily to be the same suit. For example, a hand containing 7 club, 6 spade, 5 spade, 4 heart and 3 diamond forms a straight. In this problem, we extend the definition of a straight to allow 3 to 5 cards of sequential rank. Hence a hand containing K spade, Q club, and J heart is also a straight.
Mr. Panda is playing a poker game called Straight Master. The game uses a large deck of card that has N ranks from 1 to N. The rule of the game is simple: split the cards in Mr. Panda‘s hand into several straights of length from 3 to 5.
Now given a hand of cards, can you help Mr. Panda to determine if it is possible to split the cards into straights?
he first line of the input gives the number of test cases, T. T test cases follow.
Each test case contains two lines. The first line contains an integer N, indicating the number of ranks in the deck. The next line contains N integers a1, a2, ..., aNindicating the number of cards for each rank in Mr. Panda‘s hand.
- 1 ≤ T ≤ 100.
- 1 ≤ N ≤ 2 × 105.
- 0 ≤ ai ≤ 109.
- .
For each test case, output one line containing "Case #x: y", where x is the test case number (starting from 1) and y is Yes if Mr. Panda can split all his cards into straights of length from 3 to 5, or No otherwise.
題目大意就是 給好多堆紙牌 我們一次可以在 相鄰的三堆各取一張紙牌 或者相鄰的四堆中各取一張紙牌 或者五堆中各取一張紙牌 問能不能 全部取完
數據量也比較大 貪心簡單做
在做這個題目前 要先搞懂一件事情 就是3 4 5可以拼成任何大於三的數字 比如 7=4+3 9=3+3+3
貪心策略趕緊並不是很好想
可以先舉例子
1 | 2 | 3 | 3 | 5 | 8 | 10 | 5 | 6 | 7 | 4 | 2 |
我在這裏放了11堆的例子 這11堆安照題目中的規則是可以取完的
為了證明他是可以取完的 我做了下面這串表 在下面中的每一行中 都有數目不少於3個的相同數字
剛才也說過 3 4 5可以組合成任何 不小於3的數字 也就是下面的每一行的個數我都可以用3 4 5獲得
1 | 2 | 3 | 3 | 5 | 8 | 10 | 5 | 6 | 7 | 4 | 2 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | |||||
1 | 1 | 1 | 1 | 1 | 1 | ||||||
1 | 1 | 1 | 1 | 1 | |||||||
2 | 2 | 2 | |||||||||
3 | 3 | 3 | 3 | 3 | |||||||
2 | 2 | 2 | 2 | 2 | |||||||
1 | 1 | 1 | 1 | ||||||||
1 | 1 | 1 |
我將上面堆 數字做下處理 如下 相鄰的相同顏色的幾堆代表這 被取走的幾堆 數值代表取多少次
1 | 2 | 3 | 3 | 5 | 8 | 10 | 5 | 6 | 7 | 4 | 2 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | |||||
1 | 1 | 1 | 1 | 1 | 1 | ||||||
1 | 1 | 1 | 1 | 1 | |||||||
2 | 2 | 2 | |||||||||
3 | 3 | 3 | 3 | 3 | |||||||
2 | 2 | 2 | 2 | 2 | |||||||
1 | 1 | 1 | 1 | ||||||||
1 | 1 | 1 |
如果 第 i 堆 比 第 i-1 堆小 就不能確定了 但是呢 第 i 堆 要滿足一個條件 就是不能斷了 前兩堆 產生的新最左端位置 意思就是 第i堆的數目一定要 不小於 前三堆正差的和 否則會產生 一個斷層就 無解了 在這一堆的結束位置也要滿足一個條件 就是 倒數第二堆不能產生新的左端點 如果產生 就要n+1給補上 顯然是不可以的 還有就是 倒數第三堆 產生的 左端點 一定要 由末尾補上 否則 也是無解
#include<iostream> #include<stdio.h> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int maxn = 2e5+7; int a[maxn],b[maxn],flag; int main() { int T,n,cases=0; scanf("%d",&T); while(T--){ scanf("%d",&n); n++; flag=0; for(int i=2;i<=n;i++){ scanf("%d",a+i); b[i]=max(a[i]-a[i-1],0); } if(n<=3){ printf("Case #%d: No\n",++cases); continue; } for(int i=2;i<=n;i++){ if(a[i]<b[i-1]+b[i-2]) flag=1; } if(!(b[n]==0&&b[n-1]==0&&a[n]>=b[n-2])) { flag=1; } if(!flag) printf("Case #%d: Yes\n",++cases); else printf("Case #%d: No\n",++cases); } return 0; }
Straight Master (貪心)