BestCoder Round #93 ABC
2017-04-04 19:05
369 查看
A:
题目大意:
将数组划分成最少的段,每段的数两两不同。
题解:直接用一个map记录一个数是否出现过,贪心的每次取最多个数就好。
B:
题目大意:
给出一个0-9组成的字符串,问能否删掉K个数字,使得最后形成的数没有前导零且能被3整除。
题解:
最后会留下N-K个数,枚举第一个数的位置,然后问题就可以转化为判断同余方程0*x+1*y+2*z = v (mod 3) 是否有解。 其中(x+y+z=K-1 && x<=a && y<=b && z<=c)
设:
x = i (mod 3)
y = j (mod 3)
z = k (mod 3)
在[0,2]范围里枚举i,j,k
然后可行的条件是:
1. i<=a , j <=b , k <=c
2. 0*i+1*j+2*k = v (mod 3)
3. i+j+k <= K-1
4. 3*( (a-i)/3+(b-j)/3+(c-k)/3 )+ i+ j + k >= K-1
代码:
View Code
题目大意:
将数组划分成最少的段,每段的数两两不同。
题解:直接用一个map记录一个数是否出现过,贪心的每次取最多个数就好。
B:
题目大意:
给出一个0-9组成的字符串,问能否删掉K个数字,使得最后形成的数没有前导零且能被3整除。
题解:
最后会留下N-K个数,枚举第一个数的位置,然后问题就可以转化为判断同余方程0*x+1*y+2*z = v (mod 3) 是否有解。 其中(x+y+z=K-1 && x<=a && y<=b && z<=c)
设:
x = i (mod 3)
y = j (mod 3)
z = k (mod 3)
在[0,2]范围里枚举i,j,k
然后可行的条件是:
1. i<=a , j <=b , k <=c
2. 0*i+1*j+2*k = v (mod 3)
3. i+j+k <= K-1
4. 3*( (a-i)/3+(b-j)/3+(c-k)/3 )+ i+ j + k >= K-1
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <cmath> #include <queue> using namespace std; #define X first #define Y second #define N 100010 #define M 11 typedef long long ll; const int Mod=1000000007; const int INF=1<<30; char s[26]; int cnt[27],a[10],b[10]; int pw[27]; bool vis[26]; int Lcm(int x,int y) { int lcm=x*y,tmp; while (y) { tmp=x%y; x=y,y=tmp; } return lcm/x; } int Power(int x,int P) { if (pw[x]) return pw[x]; int res=1,xx=x; for (;P;P>>=1) { if (P&1) res=1ll*res*x%Mod; x=1ll*x*x%Mod; } return pw[xx]=res; } int Solve(int len,int n) { //for (int i=0;i<n;i++) cout<<i<<" "<<a[i]<<" "<<b[i]<<endl; int lim=1<<n,val,cnt,m,t,res=0; for (int mask1=1;mask1<lim;mask1++) { val=1; t=0; for (int i=0;i<n;i++) if (mask1&(1<<i)) val=Lcm(val,a[i]),t+=b[i]; cnt=Power(t,len); for (int mask2=(mask1-1)&mask1;mask2;mask2=(mask2-1)&mask1) { int op=1; m=t; for (int j=0;j<n;j++) if (mask2&(1<<j)) op=-op,m-=b[j]; cnt+=op*Power(m,len); cnt%=Mod; } res+=1ll*cnt*val%Mod; res%=Mod; } return res<0? res+Mod:res; } int main() { //freopen("in.in","r",stdin); //freopen("out.out","w",stdout); int T,len; scanf("%d",&T); while (T--) { scanf("%d%s",&len,s); memset(vis,0,sizeof(vis)); memset(cnt,0,sizeof(cnt)); memset(pw,0,sizeof(pw)); for (int i=0;i<26;i++) { if (!vis[i]) { int c=0,x=i; do { c++; x=s[x]-'a'; vis[x]=true; }while (x!=i); cnt[c]+=c; } } int n=0; for (int i=1;i<=26;i++) if (cnt[i]) a =i,b[n++]=cnt[i]; printf("%d\n",Solve(len,n)); } return 0; }
View Code
相关文章推荐
- BestCoder Round #93
- BestCoder Round #93
- hdu 5776 sum(BestCoder Round #85——思维题)
- 【HDU5804 BestCoder Round 86A】【水题】Price List
- BestCoder Round 50 (div 2)
- 【HDU5563 BestCoder Round 62 (div1)A】【计算几何 凸包】Clarke and five-pointed star 正五边形判定 正五角星判定
- 【BestCoder Round 65C】【树状数组 动态查找第k大 O(nlogn)】ZYB's Premutation 告诉你前i个数中的逆序对数让你还原全排列
- BestCoder Round #70 Jam's store(网络流)
- BestCoder Round #75
- BestCoder Round #75
- BestCoder Round #28
- 【HDU5805 BestCoder Round 86B】【前后缀和】NanoApe Loves Sequence 删除一数后数列max(相邻数绝对值)
- Bestcoder Round#49 1001Untitled
- hdu 4883 bestcoder round 2 1001 TIANKENG’s restaurant
- 【BestCoder Round 65D】【树形DP 容斥思想】ZYB's Tree 求距离每个节点距离不超过k的节点数
- BestCoder Round #20 A
- BestCoder(Valentine's Day Round C题) hdu5176 The Experience of Love
- BestCoder Round #33——1001——zhx's submissions
- BestCoder Round #29——A--GTY&#39;s math problem(快速幂(对数法))、B--GTY&#39;s birthday gift(矩阵快速幂)
- BestCoder Round #75 King's Cake 模拟&&优化 || gcd