设为首页 加入收藏

TOP

ural 1932 The Secret of Identifier (容斥原理)
2015-07-20 17:59:36 来源: 作者: 【 】 浏览:2
Tags:ural 1932 The Secret Identifier 容斥 原理

题目大意:

求出给的n个串中。

精确到只有一个字符不同,两个字符不同,三个字符不同,四个字符不同的对数。


思路分析:

枚举状态。

dp[i] [j] ...表示当前串取出 i 状态下的所有字符转化成十进制数为 j 的出现的次数。

这样的话,就记录了所有串的子串的状态。

然后计数就得到了所有的状态。

然后我们要得到精确不同的,可以用补集的思想,如果要精确到三个不相同,意味着要精确到1 个是相同的。


注意的问题是

在最后要运用容斥去重。

#include 
  
   
#include 
   
     #include 
    
      #include 
     
       using namespace std; typedef long long ll; char str[6]; ll dp[16][1<<16]; int trans(char ch) { if(isdigit(ch))return ch-'0'; return ch-'a'+10; } int Count(int x) { int ret=0; while(x){ ret+=(x&1); x>>=1; } return ret; } ll tmp[5],ans[5]; int main() { int n; while(scanf("%d",&n)!=EOF) { int maxm=-1; memset(dp,0,sizeof dp); memset(tmp,0,sizeof tmp); for(int i=1;i<=n;i++) { scanf("%s",str); for(int s=1;s<16;s++) { int t=0; if(s&8) t += trans(str[0])*(1<<12); if(s&4) t += trans(str[1])*(1<<8); if(s&2) t += trans(str[2])*(1<<4); if(s&1) t += trans(str[3]); dp[s][t]++; maxm=max(t,maxm); } } for(int s=1;s<16;s++) { int x=Count(s); for(int i=0;i<=maxm;i++) { tmp[x]+=dp[s][i]*(dp[s][i]-1)/2; } } ans[1]=tmp[3]; ans[2]=tmp[2]-3*tmp[3]; ans[3]=tmp[1]-2*tmp[2]+3*tmp[3]; printf("%I64d %I64d %I64d %I64d\n",ans[1],ans[2],ans[3],(ll)n*(n-1)/2-ans[1]-ans[2]-ans[3]); } return 0; } 
     
    
   
  


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇POJ 3318 Matrix Multiplication(.. 下一篇HDU 4902 Nice boat(线段树 区间..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: