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;
	}
};
时间: 2024-07-31 19:03:17

TC TCO2015R1A(Similars-状态压缩)的相关文章

状态压缩DP SRM 667 Div1 250

题意:给n个01串,设计一种顺序,使得每次新出现的1的个数^2和最小 分析:比赛时不知道是div1的题,以为暴力贪心可以过,结果被hack掉了.题解说没有充分的证明使用贪心是很有风险的,正解是用状态压缩DP,详细解释. 收获:爆零还能涨分,TC真奇怪. 代码: int dp[(1<<20)+10]; int a[55]; class OrderOfOperations { public: int minTime( vector <string> s ) { int n = s.si

胜利大逃亡(续)(状态压缩bfs)

胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7357    Accepted Submission(s): 2552 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带

uva 818(dfs+图+状态压缩)

题意:有n个环,编号从1到n,给出了一些环环相扣的情况,比如给a和b表示a和b两个环的扣在一起的,每个环都是可以打开的,问最少打开多少个环,然后再扣好,可以让所有的环成为一条链. 题解:状态压缩把所有的打开环的情况枚举出来,然后拿去判断是否成立,更新打开环后的图g[i][j],和每个点的度数,不成立有三种情况,1.计算没有打开的环的度数,如果大于2说明不会有链,2.把没有打开环拿去dfs,访问过就vis[i]++,如果vis[i]>=2说明存在环,3.如果打开的环数num + 1小于链的数量,说

POJ 3254 Corn Fields 状态压缩DP (C++/Java)

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反

uva 11195 Another queen (用状态压缩解决N后问题)

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2136 Problem A Another n-Queen Problem I guess the n-queen problem is known by every person who has studied backtracking. In this problem you s

dp状态压缩

dp状态压缩 动态规划本来就很抽象,状态的设定和状态的转移都不好把握,而状态压缩的动态规划解决的就是那种状态很多,不容易用一般的方法表示的动态规划问题,这个就更加的难于把握了.难点在于以下几个方面:状态怎么压缩?压缩后怎么表示?怎么转移?是否具有最优子结构?是否满足后效性?涉及到一些位运算的操作,虽然比较抽象,但本质还是动态规划.找准动态规划几个方面的问题,深刻理解动态规划的原理,开动脑筋思考问题.这才是掌握动态规划的关键. 动态规划最关键的要处理的问题就是位运算的操作,容易出错,状态的设计也直

HDU3001(KB2-J 状态压缩dp)

Travelling Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8103    Accepted Submission(s): 2642 Problem Description After coding so many days,Mr Acmer wants to have a good rest.So travelling is

2017盛大游戏杯 零件组装(状态压缩DP之巧妙枚举子集)

题目链接:2017盛大游戏杯 零件组装 题意: 有n个零件,给你相邻关系和排斥关系,每两块零件组装起来有一个代价,问最少的代价总和是多少. 题解: 考虑状态压缩,dp[i]表示i这个集合为一个零件块. 那么要枚举一下i的子集.O(3^n). 先要预处理一下每个集合的排斥个数和相邻个数,然后容斥一下就可以了. 1 #include<bits/stdc++.h> 2 #define mst(a,b) memset(a,b,sizeof(a)) 3 #define F(i,a,b) for(int

HDU1565(状态压缩dp)

方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8170    Accepted Submission(s): 3095 Problem Description 给你一个n*n的格子的棋盘,每个格子里面有一个非负数.从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数