【GDOI2016模拟3.10】习用之语

题意

给定N个长度均为四的字符串,问他们恰好有K个字母不同的字符串有多少对(相同位置),其中字符集为0~9,a~z. n 50000

分析

十分显然一道题目,暴力 N2 嘛,优化起来很快。
我们考虑一种情况:有L个字符相同——注意并不是恰好——枚举其中不同的位置为 P1...PL 。这样的话求有多少对就很方便了,这是谁都能想到的方法,随便用点算法把原来所有字符串分成若干块(比如排序~~~),每块里的字符串都有指定位置上的字母相同,其他没有指定的位置我们不管。若有X个块,每个块有 Sizex 个字符串,那么这种情况的对数就是 sizex(sizex1)/2
这样我们得到很多种情况的答案。很明显,要恰好,就是容斥一下的问题了,由于K最大只有4,所以明显可以过。

代码

#include<cstdio> #include<algorithm> #include<iostream> #define fo(i,j,k) for(i=j;i<=k;i++) using namespace std; const int N=50005; struct rec { int a[4],cmp; }b[N]; int a[N][4],n,dd,i,j,c[4],dur,tt,kx,q1,l,rt; long long ans,asw[20],as; char s[4]; bool cmp(rec a,rec b){return a.cmp<b.cmp;} int cmp1(rec a,rec b) { int i=0; while (a.a[i]==b.a[i]&&i<3) i++; return i; } int get(int x) { int i,j; ans=0; fo(i,1,n) { dur=0; tt=-1; fo(j,0,3) if (c[j]!=-1) { dur=dur*36+a[i][j]; b[i].a[++tt]=a[i][j]; } fo(j,0,3) if (c[j]==-1) { dur=dur*36+a[i][j]; b[i].a[++tt]=a[i][j]; } b[i].cmp=dur; } sort(b+1,b+1+n,cmp); dur=1; tt=0; fo(i,2,n) { kx=cmp1(b[i],b[i-1]); if (kx>=x) dur++; else { ans+=(long long)(dur)*(dur-1)/2; dur=1; } } ans+=(long long)(dur)*(dur-1)/2; return ans; } int main() { scanf("%d%d\n",&n,&dd); c[0]=c[1]=c[2]=c[3]=-1; fo(i,1,n) { scanf("%s\n",s); fo(j,0,3) { if (s[j]>='0'&&s[j]<='9')  a[i][j]=s[j]-'0'; else a[i][j]=s[j]-'a'+10; } } int d[17][5]={{0,0,0,0,0},{1,1,1,1,4},{1,1,1,-1,3},{1,1,-1,1,3},{1,-1,1,1,3},{-1,1,1,1,3},{1,1,-1,-1,2},{1,-1,1,-1,2},{1,-1,-1,1,2},{-1,1,1,-1,2},{-1,1,-1,1,2},{-1,-1,1,1,2},{1,-1,-1,-1,1},{-1,1,-1,-1,1},{-1,-1,1,-1,1},{-1,-1,-1,1,1},{-1,-1,-1,-1,0}}; //这是打情况表 fo(i,1,16) { fo(j,0,3) c[j]=d[i][j]; if (i==13) { i=i; } asw[i]=get(d[i][4]); for(l=1;l<i;l++) { rt=0; fo(j,0,3) if (d[l][j]==d[i][j]&&d[l][j]==1) rt++; if (rt==d[i][j]&&d[l][j]>=d[i][j]+1) asw[i]-=asw[l]; } if (4-d[i][4]==dd) as+=asw[i]; } printf("%lld\n",as); }

反思

这道题比赛的时候千辛万苦,改了5遍终于对了,最后对拍错了搞得我交题时还忧心忡忡。问题是很明显的。
1,审题不严谨,条件看着看着忘了。
2,构思的时候十分马虎,先想了算法,就是排序维护一种情况,然而把它打出来了以后我居然还不是很了解这个东西是干什么的,三番五次改程序各种地方,还怀疑是维护的姿势不对。
3,最后没时间了才紧张思考,按逻辑走,很快想通,思想也是十分简单,调试基本不用。
这道题浪费了大量时间做无用功,好的开端是成功的一半啊···

你可能感兴趣的:(【GDOI2016模拟3.10】习用之语)