您的位置:首页 > 其它

Cf 104 div.2

2012-01-23 19:21 399 查看
A题

if all digits are lucky and sum of the digits of the first half equals to the sum of the digits of the second half, then answer is YES, in other case - NO.
All this can be checked by single loop through all the digits

B题

in worst case, the answer will be equal to 177777. It can't be greater. So, only thing you need is to write some function F(x)which
will return mask of the x. After that you need to write such kind of code:

x = a + 1;

while (F(x) is not equal to b)

increase x;

and x will contain the answer.

C题

You need to find two numbers: c47 (number
of such positions i, that ai = 4 and bi = 7)
and c74 (number of such positions
that ai = 7 and bi = 4).
After that the result will be max(c47, c74) (because
you need to obtain min(c47, c74) swaps,
the rest max(c47, c74) - min(c47, c74)are
editings of digits).

D题

这题,比赛的时候花了一个小时,结果还是wa。。。

我花了20分钟的时间推出了个结论,如果 | a3-a4 | > 1,则输出 -1 。。。这个很重要。

1、a3==a4

细分:

1、 a1==a3 && a2>a4 2、a1>a3 && a2==a4 3、a1>a3&& a2>a4

2、a3== a4+1

必须: a1>=a3 && a2>=a3

4...4747474777...7

3、a4== a3+1

必须: a1>=a4 && a2>=a4

比较特殊的吧:

74

74444...4

77774444

7444...44747477...774

E题

首先,相同的lucky num数放一起,

题目转换成,n个数里面挑k个数来乘,把所有的结果累加,注意取模。

开始是想dp[][],可以搞定,可是n,k如此大,吗,,,,,,,,,看题解,它说lucky num在[1, 10^9]里就1022个,顿时傻眼,于是就明朗了。

设cnt为非lucky_num的个数;

C( cnt, t ) * dp[ n ][ k-t ] % mod; 注意,我这里一直错误。。。t有界限的,

for ( t= max( 0, k-n ); t<=k && t<=cnt ; ++t )

关于C(a,b)%mod,我是考虑到a,b<=10^5, 可以事先打表搞定 x! % mod, 注意下面一个大牛的代码,把逆元也事先全部算出来了,这个在ACM的比赛里确实是值得借鉴。

我的代码:

/*Jan 23, 2012 12:40:06 PM	yimao	 E - Lucky Subsequence	 GNU C++	Accepted	 280 ms	 10900 KB*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
#define MM(a,b) memset(a,b,sizeof(a));
typedef unsigned long long u64;
typedef long long lld;
#define maxn 100050
#define mod 1000000007

map<string,int>M;

bool judge(string x){
for(int i=0;i<x.size();++i)
if( x[i]!='4'&&x[i]!='7' ) return 0;
return 1;
}

// dp[i][j]: the number of within [1,i],choose j lucky number;
int a[1050];
lld dp[1050][1050]; // the number of lucky number if 1022 in [1,10^9];
void DP(int n,int k){
MM( dp, 0 );
for(int i=0;i<=n;++i) dp[i][0]= 1; /////// i=0;
for(int i=1;i<=n;++i){
for(int j=1;j<=k&&j<=i;++j){
dp[i][j]= (dp[i-1][j] + (a[i]*dp[i-1][j-1])%mod) %mod;
}
}
}

lld x[maxn];
void Init(){
x[0]=1;
for(lld i=1;i<=100000;++i)
x[i]= (x[i-1]*i)%mod;
}

lld Pow_mod(lld x,lld k){
lld r=1,t=x%mod;
while(k){
if(k&1) r= r*t%mod;
t= t*t%mod;
k>>=1;
}
return r%mod;
}
// calu C(a,b)%p, p is a prime(1000000007),a,b<=10^5;
lld Comb(int a,int b){
lld t= (x[b]*x[a-b])%mod;
lld w= Pow_mod( t, mod-2 );
return ( x[a]* w )%mod;
}

int main()
{
//freopen("E.txt","r",stdin);
int i,n,k;
Init();
while(cin>>n>>k){
if( !M.empty() ) M.clear();
string ch;
int cnt=0; // num of digit 1;
for(i=0;i<n;++i){
cin>> ch;
if( judge(ch)==0 ) cnt++;
else{
if( M.find(ch)==M.end() )
M[ch]=1;
else M[ch]++;
}
}
//if( k>n ) { puts("0"); continue; } the problem says k<=n;

n= 0;
for(map<string,int>::iterator it= M.begin();it!=M.end();++it){
a[++n]= it->second;
}
//printf("n=%d\n",n);

DP(n,k);
lld sum=0;
//for(i=0;i<=cnt&&i<=k;++i){
for(i=max(0,k-n);i<=cnt&&i<=k;++i){
sum+= ( Comb(cnt,i) * dp
[k-i] )%mod;
if( sum>=mod ) sum-= mod;
}
cout<< sum <<endl;
}
}


一个大牛的代码,非常nb:

#include<stdio.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<set>
#include<bitset>
#include<map>
#include<vector>
#include<string.h>
#include<algorithm>
#include<iostream>
#define pb push_back
#define MOD 1000000007
using namespace std;
vector<int>lucky;
void dfs(int x){
int y;
if(x>=100000000)return;
y=x*10+4;
lucky.pb(y);
dfs(y);
y=x*10+7;
lucky.pb(y);
dfs(y);
}
int a[1024];
long long dp[1024],inv[100010],fac[100010];
long long mypow(long long x,long long y){
long long an=1;
while(y){
if(y&1){
an*=x;
an%=MOD;
}
y>>=1;
x*=x;
x%=MOD;
}
return an;
}
int main(){
int i,j,k,n,non=0,m;
fac[0]=inv[0]=1;
for(i=1;i<=100000;i++){
fac[i]=fac[i-1]*i%MOD;
}
inv[100000]=mypow(fac[100000],MOD-2);
for(i=99999;i>0;i--)inv[i]=inv[i+1]*(i+1)%MOD;
dfs(0);
sort(lucky.begin(),lucky.end());
scanf("%d%d",&n,&k);
m=min((int)lucky.size(),k);
for(i=0;i<n;i++){
int x;
scanf("%d",&x);
int tmp=lower_bound(lucky.begin(),lucky.end(),x)-lucky.begin();
if(tmp>=lucky.size())non++;
else if(lucky[tmp]==x)a[tmp]++;
else non++;
}
dp[0]=1;
for(i=0;i<lucky.size();i++){
for(j=m;j>0;j--){
dp[j]=(dp[j-1]*a[i]+dp[j])%MOD;
}
}
long long an=0;
for(i=0;i<=m;i++){
if(k-i>non)continue;
an+=dp[i]*fac[non]%MOD*inv[k-i]%MOD*inv[non-(k-i)]%MOD;
}
an%=MOD;
if(an<0)an+=MOD;
cout<<an<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: