Codeforces Round #179 (Div. 2) B. Yaroslav and Two Strings(容斥原理)

 

题目大意

 

对于两个数字串 S 和 W,如果存在 i 和 j 使得:S(i)>W(i) && S(j)<W(j) 那么说这两个串是不可比较的,现在给了两个长度均为 n(1≤n≤105) 的串 S 和 W,用 '?' 代表未知的字母,问,有多少种可能的情况,使得 S  和 W 不可比较?

 

做法分析

 

这是 Div2 为数不多的比较坑的题目,当时比赛的时候貌似的时候才两三百人过

 

         求出所有可能的情况的数量,设为 ans

         求出 S 比 W 大的情况,即:S(i)≥W(i) 的情况数量,设为 res1

         求出 S 比 W 小的情况,即;S(i)≤W(i) 的情况数量,设为 res2

         求出 S 和 W 相等的情况,即:S(i)==W(i) 的情况数量,设为 res3

 

那么,利用容斥原理:最后的结果应该是 ans-res1-res2+res3

 

参考代码

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 const int N=100006;
 9 const int MOD=1000000007;
10 
11 char S[N], W[N];
12 int n, cnt;
13 
14 LL calMax()
15 {
16     LL res=1;
17     for(int i=0; i<n; i++)
18     {
19         if(S[i]!='?' && W[i]!='?')
20         {
21             if(S[i]>=W[i]) res*=1;
22             else res*=0;
23             continue;
24         }
25         if(S[i]!='?') res=(res*(S[i]-'0'+1))%MOD;
26         else if(W[i]!='?') res=(res*('9'-W[i]+1))%MOD;
27         else res=(res*55)%MOD;
28     }
29     return res;
30 }
31 
32 LL calMin()
33 {
34     LL res=1;
35     for(int i=0; i<n; i++)
36     {
37         if(S[i]!='?' && W[i]!='?')
38         {
39             if(S[i]<=W[i]) res*=1;
40             else res*=0;
41             continue;
42         }
43         if(S[i]!='?') res=res*('9'-S[i]+1)%MOD;
44         else if(W[i]!='?') res=res*(W[i]-'0'+1)%MOD;
45         else res=res*55%MOD;
46     }
47     return res;
48 }
49 
50 LL calEqu()
51 {
52     LL res=1;
53     for(int i=0; i<n; i++)
54     {
55         if(S[i]!='?' || W[i]!='?')
56         {
57             if(S[i]!='?' && W[i]!='?' && S[i]!=W[i]) res=0;
58             continue;
59         }
60         res=res*10%MOD;
61     }
62     return res;
63 }
64 
65 int main()
66 {
67     scanf("%d", &n);
68     scanf("%s%s", S, W);
69     cnt=0;
70     for(int i=0; i<n; i++)
71     {
72         if(S[i]=='?') cnt++;
73         if(W[i]=='?') cnt++;
74     }
75     LL ans=1;
76     for(int i=0; i<cnt; i++) ans=(ans*10)%MOD;
77     LL res1=calMax(), res2=calMin(), res3=calEqu();
78     printf("%I64d\n", (ans-res1-res2+res3+MOD+MOD)%MOD);
79     return 0;
80 }
B. Yaroslav and Two Strings

 

题目链接 & AC通道

 

Codeforces Round #179 (Div. 2) B. Yaroslav and Two Strings

 

 

 

posted @ 2013-05-14 00:23  jianzhang.zj  阅读(357)  评论(0编辑  收藏  举报