TC TCO2015R1A(Similars-状态压缩)

Problem Statement

 

Given two positive integers x and y, their similarity S(x, y) is defined as follows: To compute S(x, y) we count all d between 0 and 9, inclusive, such that both x and y contain the digit d when written in base 10 (without any leading zeros). For example, S(1123, 220181) = 2 since both numbers contain the digit 1 and both contain the digit 2.

You are given two ints L and R that define a range. Find two distinct integers in this range that have the largest similarity. Formally, return the maximum of S(a, b) over all a, b such thatL <= a < b <= R.

Definition

 
Class:Similars
Method:maxsim
Parameters:int, int
Returns:int
Method signature:int maxsim(int L, int R)
(be sure your method is public)

Limits

 
Time limit (s):2.000
Memory limit (MB):256
Stack limit (MB):256

Constraints

-

R will be between 2 and 100,000, inclusive.

-

L will be between 1 and R - 1, inclusive.

Examples

0) 
 
1
10
Returns: 1
We have S(1, 10) = 1 since both numbers contain the digit 1. All other pairs of numbers within this range have similarity 0.
1) 
 
1
99
Returns: 2
There are many pairs with similarity 2, for example pairs (23,32) and (38,83).
2) 
 
99
100
Returns: 0
Here we have only one pair (99, 100) and its similarity is 0.
3) 
 
1000
1010
Returns: 2
4) 
 
444
454
Returns: 2



直接把每个数根据数位状压成一个数,共2^10 统计即可


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define MEM(a) memset(a,0,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define MAXN (100000)
typedef long long ll;
int f[MAXN]={0},g[MAXN]={0};
int p2[20]={1,2,4,8,16,32,64,128,256,512,1024};
class Similars
{
public:
	int maxsim(int L, int R)
	{
		int ans=0;
		p2[0]=1;
		For(i,10) p2[i]=p2[i-1]*2;
		MEM(f)
		Fork(i,L,R)
			{
				int p=i,t=0;
				while (p)
				{
					t=t|p2[p%10];
					p/=10;
				}
				f[t]++;				
			}
		Rep(i,p2[10])
		{
			int q=0;
			Rep(j,10) if (i&p2[j]) q++;
			g[i]=q;
		}
		
		Rep(i,p2[10])
			Rep(j,p2[10])
			{
				if ( (i==j && f[i]>=2) || (i!=j && f[i] && f[j] ))	
				{
					ans=max(ans,g[i&j]);
				}		
			} 
		
		
		
		return ans;	
	}
};






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值