[JSOI2007]麻將 模擬 BZOJ1028
阿新 • • 發佈:2019-02-02
sstream time type 同時 sample etc pragma const bsp
題目描述
麻將是中國傳統的娛樂工具之一。麻將牌的牌可以分為字牌(共有東、南、西、北、中、發、白七種)和序數牌(分為條子、餅子、萬子三種花色,每種花色各有一到九的九種牌),每種牌各四張。
在麻將中,通常情況下一組和了的牌(即完成的牌)由十四張牌組成。十四張牌中的兩張組成對子(即完全相同的兩張牌),剩余的十二張組成三張一組的四組,每一組須為順子(即同花色且序數相連的序數牌,例如條子的三、四、五)或者是刻子(即完全相同的三張牌)。一組聽牌的牌是指一組十三張牌,且再加上某一張牌就可以組成和牌。那一張加上的牌可以稱為等待牌。
在這裏,我們考慮一種特殊的麻將。在這種特殊的麻將裏,沒有字牌,花色也只有一種。但是,序數不被限制在一到九的範圍內,而是在1到n的範圍內。同時,也沒有每一種牌四張的限制。一組和了的牌由3m + 2張牌組成,其中兩張組成對子,其余3m張組成三張一組的m組,每組須為順子或刻子。現給出一組3m + 1張的牌,要求判斷該組牌是否為聽牌(即還差一張就可以和牌)。如果是的話,輸出所有可能的等待牌。
輸入輸出格式
輸入格式:包含兩行。第一行包含兩個由空格隔開整數n, m (9<=n<=400, 4<=m<=1000)。第二行包含3m + 1個由空格隔開整數,每個數均在範圍1到n之內。這些數代表要求判斷聽牌的牌的序數。
輸出格式:輸出為一行。如果該組牌為聽牌,則輸出所有的可能的等待牌的序數,數字之間用一個空格隔開。所有的序數必須按從小到大的順序輸出。如果該組牌不是聽牌,則輸出"NO"。
輸入輸出樣例
輸入樣例#1: 復制9 4 1 1 2 2 3 3 5 5 5 7 8 8 8輸出樣例#1: 復制
6 7 9
枚舉;
#include<iostream> #include<cstdio> #include<algorithm> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #include<set> #include<vector> #include<queue> #include<bitset> #include<ctime> #include<deque> #include<stack> #include<functional> #include<sstream> //#include<cctype> //#pragma GCC optimize(2) using namespace std; #define maxn 200005 #define inf 0x7fffffff //#define INF 1e18 #define rdint(x) scanf("%d",&x) #define rdllt(x) scanf("%lld",&x) #define rdult(x) scanf("%lu",&x) #define rdlf(x) scanf("%lf",&x) #define rdstr(x) scanf("%s",x) typedef long long ll; typedef unsigned long long ull; typedef unsigned int U; #define ms(x) memset((x),0,sizeof(x)) const long long int mod = 1e9; #define Mod 1000000000 #define sq(x) (x)*(x) #define eps 1e-5 typedef pair<int, int> pii; #define pi acos(-1.0) //const int N = 1005; #define REP(i,n) for(int i=0;i<(n);i++) typedef pair<int, int> pii; inline int rd() { int x = 0; char c = getchar(); bool f = false; while (!isdigit(c)) { if (c == ‘-‘) f = true; c = getchar(); } while (isdigit(c)) { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } return f ? -x : x; } ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a%b); } int sqr(int x) { return x * x; } /*ll ans; ll exgcd(ll a, ll b, ll &x, ll &y) { if (!b) { x = 1; y = 0; return a; } ans = exgcd(b, a%b, x, y); ll t = x; x = y; y = t - a / b * y; return ans; } */ int n, m; int but[maxn]; bool fg; int tmp[maxn]; bool OK() { for (int i = 1; i <= n; i++) { if (but[i] >= 2) {// 對子 but[i] -= 2; bool ok = 1; for (int j = 1; j <= n + 2; j++)tmp[j] = but[j]; for (int j = 1; j <= n + 2; j++) { if (tmp[j] < 0) { ok = 0; break; } tmp[j] %= 3; tmp[j + 1] -= tmp[j]; tmp[j + 2] -= tmp[j]; } but[i] += 2; if (ok)return true; } } return false; } int main() { //ios::sync_with_stdio(0); n = rd(); m = rd(); for (int i = 1; i <= 3 * m + 1; i++) { int x; x = rd(); but[x]++; } for (int i = 1; i <= n; i++) { but[i]++; if (OK()) { fg = 1; cout << i << ‘ ‘; } but[i]--; } if (fg == 0)cout << "NO" << endl; return 0; }
[JSOI2007]麻將 模擬 BZOJ1028