NOIp2018集训test-9-5(am)

Problem A. maze

递归处理,题解写得真简单。

我大概这辈子也写不出来这种东西吧。

 

Problem B. count

容易发现合法的数中一定有且仅有两个数加起来等于10,其他数两两配对加起来等于9或者0。

考场上就随便统计了下数的个数,然后组合数给每个不够的数配,结果忘了还有?和?配的情况,下来??随便选了下,发现会有重复的部分,大概只能dp了。

枚举加起来等于10的数是哪两个,然后dp。

f[i][j](0<=i<=4)表示 0/9,1/8……i/9-i的数量已经确定了,用了j个?的方案数。因为?只有1000个,可以随便转移。

0,9比较特殊,我预处理初状态的时候特殊考虑,枚举放几个0放几个9,只要个数和为偶数且0的个数多于9即可,后面的数确定了i的个数就可以确定9-i的个数了,可以直接转移。

具体还要枚举的加起来10的数的处理,看代码吧。

 1 //Achen
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<vector>
 7 #include<cstdio>
 8 #include<queue>
 9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define Formylove return 0
13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
15 const int N=1e5+7,p=1e9+7;
16 typedef long long LL;
17 typedef double db;
18 using namespace std;
19 LL ans,fac[N],inv[N],f[6][1003];
20 int n,cnt[12],tot;
21 char s[N];
22 
23 template<typename T>void read(T &x)  {
24     char ch=getchar(); x=0; T f=1;
25     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
26     if(ch=='-') f=-1,ch=getchar();
27     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
28 }
29 
30 LL C(int n,int m) {
31     if(n<m) return 0;
32     return fac[n]*inv[m]%p*inv[n-m]%p; 
33 }
34 
35 #define ANS
36 int main() {
37 #ifdef ANS
38     freopen("count.in","r",stdin);
39     freopen("count.out","w",stdout);
40 #endif
41     scanf("%s",s);
42     n=strlen(s);
43     fac[0]=inv[0]=inv[1]=1;
44     For(i,1,n) fac[i]=fac[i-1]*i%p;
45     For(i,2,n) inv[i]=(p-p/i*inv[p%i]%p)%p;
46     For(i,2,n) inv[i]=inv[i-1]*inv[i]%p;
47     For(i,0,n-1) {
48         if(s[i]=='?') tot++;
49         else cnt[s[i]-'0']++;
50     }
51     For(sp,1,5)  {
52         int t1=sp,t2=10-sp;
53         memset(f,0,sizeof(f));
54         For(i,0,tot) For(j,0,tot-i) { //i个0 j个9 
55             if((cnt[0]+i<cnt[9]+j-(t2==9))||(t2==9&&cnt[9]+j==0)) continue;
56             if((cnt[0]+i+cnt[9]+j-(t2==9))%2==1) continue;
57             (f[0][i+j]+=C(tot,i)*C(tot-i,j)%p)%=p;
58         }
59         For(i,0,3) For(j,0,tot) if(f[i][j]) {
60             For(k,0,tot-j) {//k个i+1 
61                 int l=cnt[i+1]+k-(t1==i+1)-cnt[8-i]+(t2==8-i);
62                 if(t1==t2) l=cnt[i+1]+k-cnt[8-i]+2*(t2==8-i);
63                 if(l<0||l+k+j>tot) continue;
64                 (f[i+1][j+k+l]+=f[i][j]*C(tot-j,k)%p*C(tot-j-k,l)%p)%=p; 
65             } 
66         }
67         ans=(ans+f[4][tot])%p;
68     }
69     printf("%lld\n",ans);
70     Formylove;
71 }
View Code

 

Problem C. sequence

我考场上的代码完全瞎那啥在扯淡,我还以为自己能A,我怕不是是个智障哦

还没改出来

 

posted @ 2018-09-06 08:04  啊宸  阅读(149)  评论(0编辑  收藏  举报