NC21854. Problem L. Wpremig's Niuniu
描述
These days, Wpremig is addicted to play QQ Lucky NiuNiu. But it's universally acknowledged that the RP of Wpremig is always negative. So in the first day, he lost all Lucky Beans, which are the currency in this game and can be obtained freely everyday.
The second day, Wpremig decides to play another mode of NiuNiu . The rules in this mode are as following:
There are 52 CARDS in a deck, which includes 13 kinds, A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q and K. Each kind of cards has four same cards. The value of each card is equal to its number. A is equal to 1. J, Q and K are all equal to 10.
When the game starts, each gamer can obtain 4 Cards from game system and they can decide whether to be the banker. After that, everyone can obtain the fifth card. These five cards owned by a player can combine into a Niu if the sum of any three cards is a multiple of ten (including 10, 20 and 30). The sum of rest two cards is X and then X is mod 10. If the current X is zero, these five cards can combine into a NiuNiu, which is a quite awesome type in this game. (Such as “A,9,J,Q,K”). Otherwise, the type of these five cards is called Niu X. If the range of X is from 1 to 6, it is also called Small Niu; if the range of X is from 7 to 9, it is also called Big Niu. For instance, “2, 9, J, Q, K” is a Small Niu and “A, 9, Q, 3, 4” is a Big Niu. Big Niu is larger than Small Niu.
However, in five cards owned by player, if there is no three cards can combine into a Niu, it is called No Niu. No Niu is littler than any Niu X or NiuNiu absolutely. If two players have the same type of cards, Niu X is larger than Niu Y when X is larger than Y. The banker can win the game if there is no other player owning cards of which the type is larger than the banker’s.
There are three particular card types as follows:
1.Five Small Niu : all five cards are strictly less than five and the sum of five cards is less or equal to ten.
2. Five Flower Niu : all five cards are in the range of J, Q, K.
3. Bomb! : there are four cards that are the same, such as “2, 3, 3, 3, 3”.
In order to predict the type of Wpremig’s cards, he decide to evaluate his cards by the rules below:
Five Small Niu is equal to 60 points. Five Flower Niu is equal to 50 points. Bomb! is equal to 40 points. NiuNiu is equal to 30 points. And Small Niu X is equal to X points. If he owns a Big Niu X, he can get double X points. No Niu is worthless. In particular, we need to pay attention that if the type of five cards meets two or more situations, Wpremig can only get the larger points.
Now, Wpremig have gotten four cards by game system. He doesn’t know others’ cards and he is lack of calculation ability so he can only believe that the probability of each kind of the fifth card he will get is equal. Can you tell him the value of expectation of points he can get?
输入描述
There is a T in the first line. T means the number of test data. T<=100000.
Each test data includes four integers in a line which mean the four cards he have obtained.
1, 11, 12, 13 mean A, J, Q, K respectively.
输出描述
For each test data , output a integer which means the value of expectation of points Wpremig can get. (Round to the integer bits).
示例1
输入:
1 10 4 5 12
输出:
9
C++14(g++5.4) 解法, 执行用时: 700ms, 内存消耗: 2568K, 提交时间: 2018-12-22 16:28:11
#include <bits/stdc++.h> using namespace std; #define ref(i,x,y)for(int i=x;i<=y;++i) int T,a,b,c,d,w[1500],ct[1500],o[21],oN; bool mk[1100],MK[1100]; void print(int x) { if (x==0) putchar('0'); else { oN=0; while (x) o[++oN]=x%10,x/=10; for (int i=oN; i; i--) putchar(o[i]+48); } puts(""); } int main(){ cin>>T; ref(i,1,10)w[i]=i; ref(i,11,13)w[i]=10; while(T--){ scanf("%d%d%d%d",&a,&b,&c,&d); int s=w[a]+w[b]+w[c]+w[d]; ref(i,1,13)ct[i]=0; ref(i,0,10)mk[i]=MK[i]=0; ct[a]++;ct[b]++;ct[c]++;ct[d]++; mk[(w[a]+w[b])%10]=1; mk[(w[a]+w[c])%10]=1; mk[(w[b]+w[c])%10]=1; mk[(w[a]+w[d])%10]=1; mk[(w[b]+w[d])%10]=1; mk[(w[c]+w[d])%10]=1; MK[w[a]%10]=1; MK[w[b]%10]=1; MK[w[c]%10]=1; MK[w[d]%10]=1; int ans=0; ref(i,1,13){ s+=w[i]; ct[i]++; int res=0; if(s<=10&&a<5&&b<5&&c<5&&d<5&&i<5)res=max(res,60);else if(a>10&&b>10&&c>10&&d>10&&i>10)res=max(res,50);else if(ct[i]>=4||ct[a]>=4)res=max(res,40);else{ int s0=s%10; int ss0=(s0-w[i]+10)%10; if(mk[s0]||MK[ss0]) { if(s0==0)res=max(res,30);else if(s0<7)res=max(res,s0);else if(s0>=7)res=max(res,s0*2); } } s-=w[i]; ct[i]--; ans=ans+res; } print((int)round(1.0*ans/13)); } }
C++11(clang++ 3.9) 解法, 执行用时: 883ms, 内存消耗: 2520K, 提交时间: 2018-12-22 14:37:03
#include<bits/stdc++.h> using namespace std; inline void read(int &x){ x=0;char c=getchar();int f=1; while(!isdigit(c)){if(c=='-')f=-1;c=getchar();} while(isdigit(c)){x=10*x+c-'0';c=getchar();}x*=f; } int T,a,b,c,d,A[15],B[10]; inline int mxx(int x,int y){return x>y?x:y;} inline int mnn(int x,int y){return x<y?x:y;} inline int calc(int a,int b,int c,int d,int e) { int mx=mxx(a,mxx(b,mxx(c,mxx(d,e)))); if(mx<5&&a+b+c+d+e<=10)return 60; int mn=mnn(a,mnn(b,mnn(c,mnn(d,e)))); if(mn>=11)return 50; memset(A,0,sizeof(A)); A[a]++;A[b]++;A[c]++;A[d]++;A[e]++; for(int i=1;i<=13;i++)if(A[i]>=4)return 40; if(a>=10)a=0; if(b>=10)b=0; if(c>=10)c=0; if(d>=10)d=0; if(e>=10)e=0; B[1]=a;B[2]=b;B[3]=c;B[4]=d;B[5]=e; int x=(a+b+c+d+e)%10,flag=0; for(int i=1;i<=5;i++) for(int j=i+1;j<=5;j++)if(B[i]+B[j]==x||B[i]+B[j]==x+10){flag=1;break;} if(!flag)return 0; if(!x)return 30; if(x>=7)return 2*x; return x; } int main() { read(T); while(T--) { read(a),read(b),read(c),read(d); double sum=0; for(int i=1;i<=13;i++)sum+=calc(a,b,c,d,i); printf("%d\n",(int)round(sum/13.0)); } return 0; }