标签:
给出n (n<=50000) 个长度为4的字符串,问有且仅有d(1<=d<=4)处不相同的字符串有几对。
一直对着4发呆,这么小的字符串背后有什么玄学呢= =...既不能放在TRIE上搞似乎也套不了什么东西,一直很好奇这种题目能不能用某个神奇的字符串HASH水过...然后颓了一会儿突然想到,如果我们只是判断字符串相等不相等的话,因为每个位置只有36种状态,直接开个36^4的数组加加减减然后搞个组合数就好了.
那不是可以迁移过来吗?!!!!!!!
在那个问题之上,我们要解决的是两个字符串之间不同的个数---->考虑到我们可以把一个字符串拆成其按顺序的各个排列组合,然后就变成了上面的那个判定性的问题.分开来好判断,怎么把它合起来呢?容斥啊傻吊...虽然这是在OI上打的第一个容斥不过还是非常..显然?...
CODE:
/*==========================================================================
# Last modified: 2016-02-27 09:13
# Filename: t2.cpp
# Description:
==========================================================================*/
#define me AcrossTheSky
#include <cstdio>
#include <cmath>
#include <ctime>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#define lowbit(x) (x)&(-x)
#define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++)
#define FORP(i,a,b) for(int i=(a);i<=(b);i++)
#define FORM(i,a,b) for(int i=(a);i>=(b);i--)
#define ls(a,b) (((a)+(b)) << 1)
#define rs(a,b) (((a)+(b)) >> 1)
#define getlc(a) ch[(a)][0]
#define getrc(a) ch[(a)][1]
#define maxn 40
#define maxm 100000
#define pi 3.1415926535898
#define _e 2.718281828459
#define INF 1070000000
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
template<class T> inline
void read(T& num) {
bool start=false,neg=false;
char c;
num=0;
while((c=getchar())!=EOF) {
if(c==‘-‘) start=neg=true;
else if(c>=‘0‘ && c<=‘9‘) {
start=true;
num=num*10+c-‘0‘;
} else if(start) break;
}
if(neg) num=-num;
}
/*==================split line==================*/
int a[5];
ll sum[maxn][maxn][maxn][maxn],ans[10];
bool check(char c){ if (c>=‘0‘ && c<=‘9‘) return false; return true;}
void init(char *s){
FORP(i,0,15){
FORP(j,0,3)
if (i & 1<<j) a[j]=check(s[j])?s[j]-‘a‘+10:s[j]-‘0‘;
else a[j]=36;
//FORP(i,0,3) printf("%d ",a[i]); printf("\n");
sum[a[0]][a[1]][a[2]][a[3]]++;
}
//printf("\n");
}
int judge(int x){if (x<36) return 1; else return 0;}
void solve(){
FORP(k,0,36)
FORP(l,0,36)
FORP(m,0,36)
FORP(n,0,36){
ll f=judge(k)+judge(l)+judge(m)+judge(n),p=sum[k][l][m][n];
ans[f]+=(p*(p-1)/2);
}
}
int main(){
ll n,d; read(n); read(d);
FORP(i,1,n){
char s[10];
scanf("%s",s);
init(s);
}
solve();
//FORP(i,0,4) printf("%d ",ans[i]);
//cout << endl;
//FOR(d,1,4){
if (d==1) printf("%lld\n",ans[3]-4*ans[4]);
if (d==2) printf("%lld\n",ans[2]-3*ans[3]+6*ans[4]);
if (d==3) printf("%lld\n",ans[1]-2*ans[2]+3*ans[3]-4*ans[4]);
if (d==4) printf("%lld\n",ans[0]-ans[1]+ans[2]-ans[3]+ans[4]);
//}
}
标签:
原文地址:http://www.cnblogs.com/YCuangWhen/p/5222903.html