COCI2011:友好数对

校内OJ传送门

一般容斥,具体思想参考代码实现,刚开始是在读入时处理所有数的二进制子集,没看$N$的范围以为复杂度不会爆炸..

然后复杂度就爆炸了。

小优化:

每次整个载入二进制,计数。这个结束后枚举计数的状态和答案的状态。

up(i,1,(1<<10)-1)up(j,1,(1<<10)-1)if((j&i)==j)f[j]+=T[i];
up(i,1,(1<<10)-1)f[i]=(f[i]-1)*f[i]/2;

下面是代码的具体实现。

 1 //OJ 1376
 2 //by Cydiater
 3 //2016.9.18
 4 #include <iostream>
 5 #include <cstdio>
 6 #include <cstring>
 7 #include <string>
 8 #include <algorithm>
 9 #include <queue>
10 #include <map>
11 #include <ctime>
12 #include <cmath>
13 #include <iomanip>
14 #include <cstdlib>
15 using namespace std;
16 #define ll long long
17 #define up(i,j,n)        for(int i=j;i<=n;i++)
18 #define down(i,j,n)        for(int i=j;i>=n;i--)
19 const int MAXN=1<<15;
20 const int oo=0x3f3f3f3f;
21 inline ll read(){
22     char ch=getchar();ll x=0,f=1;
23     while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();}
24     while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
25     return x*f;
26 }
27 ll N,T[MAXN],num,ans=0,f[MAXN];
28 namespace solution{
29     void init(){
30         N=read();
31         memset(f,0,sizeof(f));
32         up(i,1,N){
33             ll S=0;num=read();
34             while(num>0){
35                 int tmp=num%10;
36                 S|=(1<<tmp);
37                 num/=10;
38             }
39             T[S]++;
40         }
41         up(i,1,(1<<10)-1)up(j,1,(1<<10)-1)if((j&i)==j)f[j]+=T[i];
42         up(i,1,(1<<10)-1)f[i]=(f[i]-1)*f[i]/2;
43     }
44     void slove(){
45         up(s,1,(1<<10)-1){
46             int cnt=0;
47             up(i,0,9)if(s&(1<<i))cnt++;
48             if(cnt%2)ans+=f[s];
49             else     ans-=f[s];
50         }
51     }
52     void output(){
53         cout<<ans<<endl;
54     }
55 }
56 int main(){
57     //freopen("input.in","r",stdin);
58     using namespace solution;
59     init();
60     slove();
61     output();
62     return 0;
63 }

时间: 2024-09-28 22:58:29

COCI2011:友好数对的相关文章

[coci2011]友好数对 容斥

无趣的小x在玩一个很无趣的数字游戏.他要在n个数字中找他喜欢友好数对.他对友好数对的定义是:如果有两个数中包含某一个以上相同的数位(单个数字),这两个数就是友好数对.比如:123和345 就是友好数对,因为都包含数位3,显然123和234也是由号数对.而12和34则不是友好数对,因为它们没有相同的数位. 刚拿到题没怎么读懂,因为我直观的想法是存一下扫一遍就行了,后来一想,得用容斥:又犯蠢了: 其实这道题的容斥比较基本,看代码吧: #include<iostream> #include<c

JZYZOJ1376 [coci2011]友好数对 容斥定理 状态压缩

http://172.20.6.3/Problem_Show.asp?id=1376 题意:找给出的数中含有相同数字的数对的对数. mmp数论题竟然卡快读,莫名拉低通过率什么的太过分了. 刚开始想到了怎么容斥但是没法实现,看了标程发现需要状压,我还是太菜了. 代码 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cm

蓝桥杯 算法训练 ALGO-117 友好数

算法训练 友好数 时间限制:1.0s   内存限制:256.0MB 问题描述 有两个整数,如果每个整数的约数和(除了它本身以外)等于对方,我们就称这对数是友好的.例如: 9的约数和有:1+3=4 4的约数和有:1+2=3 所以9和4不是友好的. 220的约数和有:1 2 4 5 10 11 20 22 44 55 110=284 284的约数和有:1 2 4 71 142=220 所以220和284是友好的. 编写程序,判断两个数是否是友好数. 输入格式 一行,两个整数,由空格分隔 输出格式 如

1105 判断友好数对

题目来源:https://acm.zzuli.edu.cn/zzuliacm/problem.php?id=1105Description输入两个正整数m和n,顺序输出m到n之间的所有友好数对.如果两个整数的所有正因子之和(包括1,不包括自身)等于对方,就称这对数是友好的.例如:1184和1210是友好数对,因为 1184的因子之和为1+2+4+8+16+32+37+74+148+296+592=1210 1210的因子之和为1+2+5+10+11+22+55+110+121+242+605=1

【数论】【枚举约数】【友好数】CODEVS 2632 非常好友

O(sqrt(n))枚举约数,根据定义暴力判断友好数. 1 #include<cstdio> 2 #include<cmath> 3 using namespace std; 4 int n; int limit; 5 int main() 6 { 7 scanf("%d",&n); 8 for(;;n++) 9 { 10 limit=sqrt(n); int tot=1; 11 if(limit*limit==n) tot+=limit; 12 for

1105: 判断友好数对(函数专题)

题目描述 输入两个正整数m和n,顺序输出m到n之间的所有友好数对. 如果两个整数的所有正因子之和(包括1,不包括自身)等于对方,就称这对数是友好的.例如:1184和1210是友好数对,因为 1184的因子之和为1+2+4+8+16+32+37+74+148+296+592=1210 1210的因子之和为1+2+5+10+11+22+55+110+121+242+605=1184 要求程序定义一个facsum ()函数和一个main()函数,facsum ()函数计算并返回n的所有正因子之和,其余

zzuli oj 1105 友好数对

题意描述:输入两个正整数m和n,顺序输出m到n之间的所有友好数对. 如果两个整数的所有正因子之和(包括1,不包括自身)等于对方,就称这对数是友好的.例如:1184和1210是友好数对解题思路:编写函数计算出m-n每个整数的所有正因子之和,然后利用函数算出该因子和的因子和是否等于该数本身,输出原整数与其因子和.代码实现: 1 #include<stdio.h> 2 int facsum(int n) 3 { 4 int i,sum=0; 5 for(i=1;i<n;i++) 6 { 7 i

友好数对

题意描述:输入两个正整数m和n,顺序输出m到n之间的所有友好数对. 如果两个整数的所有正因子之和(包括1,不包括自身)等于对方,就称这对数是友好的.例如:1184和1210是友好数对解题思路:编写函数计算出m-n每个整数的所有正因子之和,然后利用函数算出该因子和的因子和是否等于该数本身,输出原整数与其因子和.代码实现:#include<stdio.h>int facsum(int n){  int i,sum=0; for(i=1;i<n;i++) {  if(n%i==0)sum+=i

JZOJ5258.【NOIP2017模拟8.11】友好数对

Description Input Output Sample Input 3 5 1 8 13 7 5 4 8 3 Sample Output 7 Data Constraint Hint 显然有个O(n2)的暴力枚举,不过会超时.(但也有六十分呐) 时间主要花在了一个一个判断,我们设想能否一次性判断很多个. 两个数异或后有二进制中有两个一,就是说两个数二进制下有两位是不同的,即有ai xor 2k xor bj xor 2l=0(k!=l): 那么我们可以考虑枚举ai xor 2k,丢到ha