您的位置:首页 > 其它

UVA 12298——Super Poker II

2016-08-11 16:45 369 查看

题意:

给定一些扑克牌,问这些扑克牌选四色能组成n的方案数,其中遗失了c张牌,这c张不能用,问n从a到b的方案数。

思路:

分析每一种花色,那么每种花色组成的方案数即为x^1+x^2+x^3+x^5(改花色的牌只有1,2,3,5这四张的时候),那么对比于其他的花色,也是一样,四个花色的方案数相乘,即为所得值,那么很容易来使用FFT,注意可能会超精度,复数要用long double。

code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;

const long double PI=acos(-1.0);
typedef long double ld;

struct complex
{
long double l,r;
complex(ld ll=0.0,ld rr=0.0){
l=ll;r=rr;
}
complex operator +(const complex& B){
return complex(l+B.l,r+B.r);
}
complex operator - (const complex& B){
return complex(l-B.l,r-B.r);
}
complex operator *(const complex& B){
return complex(l*B.l-r*B.r,l*B.r+B.l*r);
}
};

/*
* 进行FFT和IFFT前的反转变换。
* 位置i和j(i二进制反转后位置)互换
* len必须是2的幂
*/
void change(complex y[],int len){
int i,j,k;
for (int i=1,j=len/2;i<len-1;i++){
if (i<j) swap(y[i],y[j]);
k=len/2;
while (j>=k){
j-=k;
k>>=1;
}
if (j<k) j+=k;
}
}
/*
* 做FFT
* len必须为2^k形式,
* on==1时是DFT,on==-1时是IDFT
*/
void fft(complex y[],int len,int on){
change(y,len);
for (int h=2;h<=len;h<<=1){
complex wn(cos(-on*2*PI/h),sin(-on*2*PI/h));
for (int j=0;j<len;j+=h){
complex w(1,0);
for (int k=j;k<j+h/2;k++){
complex u=y[k];
complex t=w*y[k+h/2];
y[k]=u+t;
y[k+h/2]=u-t;
w=w*wn;
}
}
}
if (on==-1){
for (int i=0;i<len;i++){
y[i].l/=len;
}
}
}

const int N=262144;
const int M=50005;
complex s
,c
,d
,h
;
int vis[M],pri[M],tot;
void getP(int n){
memset(vis,0,sizeof(vis));
tot=0;//vis[0]=vis[1]=1;
for (int i=2;i<n;i++){
if (!vis[i]) pri[tot++]=i;
for (int j=0;j<tot&&i*pri[j]<n;j++){
vis[i*pri[j]]=1;
if (i%pri[j]==0) break;
}
}
}

int main()
{
getP(M);int A,B,C;
while (~scanf("%d%d%d",&A,&B,&C),A+B+C){
int len=1;while(len<=B) len<<=1;len<<=2;
for (int i=0;i<=len;i++) s[i]=h[i]=c[i]=d[i]=complex(0,0);
for(int i=0; i<B; ++i) if(vis[i]) s[i]=h[i]=c[i]=d[i]=complex(1,0);
for (int i=0;i<C;i++){
char ch[3];
scanf("%s",ch);
int ln=strlen(ch),t;
sscanf(ch,"%d",&t);
if (ch[ln-1]=='S') s[t].l=0;
if (ch[ln-1]=='H') h[t].l=0;
if (ch[ln-1]=='C') c[t].l=0;
if (ch[ln-1]=='D') d[t].l=0;
}
fft(s,len,1);fft(h,len,1);
fft(c,len,1);fft(d,len,1);
for (int i=0;i<=len;i++) h[i]=h[i]*s[i]*c[i]*d[i];
fft(h,len,-1);
for (int i=A;i<=B;i++) printf("%.0f\n",fabs((double)h[i].l));
puts("");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: