歌名 - 歌手
0:00

    【GDOI2016模拟3.10】习用之语

    前言

    这道题看上去很水,结果我在比赛上浪费了N多时间在上面,但还是没AC。比赛结束后发现:实际上这道题还是是大水。

    题目

    这里写图片描述

    分析

    设字符串c1c2c3c4,其中c1、c2、c3、c4={'0''9','a''z','#'},'#'代表任意字符(例如字符串"#123"等于"0123"、"1123"、"2123"、···、“y123"、"z123")。
    f[c1][c2][c3][c4]表示目前与字符串c1c2c3c4相等的字符串有多少个;
    然后按照输入顺序,依次把输入的字符串放入f,再放入之前容斥求增加的答案就可以了。

    #include <cmath>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    const int maxlongint=2147483647;
    using namespace std;
    int m,d,n,tot,ans,b[200];
    int f[40][40][40][40];//0指'#'
    char s[5];
    int main()
    {
    	scanf("%d%d\n",&n,&d);
    	tot=0;
    	for(int g='0';g<='9';g++)
    		b[g]=++tot;
    	for(int g='a';g<='z';g++)
    		b[g]=++tot;
    	ans=0;
    	for(int q=1;q<=n;q++)
    	{
    		scanf("%s\n",s);
    		if(d==3)
    		{
    			for(int j=0;j<=1;j++)
    				for(int k=0;k<=1;k++)
    					for(int l=0;l<=1;l++)
    						for(int g=0;g<=1;g++)
    							if((j+k+l+g)==1)
    								ans+=f[j*b[s[0]]][k*b[s[1]]][l*b[s[2]]][g*b[s[3]]];
    									else 
    									if((j+k+l+g)==3)
    										ans+=f[j*b[s[0]]][k*b[s[1]]][l*b[s[2]]][g*b[s[3]]]*3;
    											else 
    												if((j+k+l+g)==2) ans-=f[j*b[s[0]]][k*b[s[1]]][l*b[s[2]]][g*b[s[3]]]*2;
    												else 
    													if((j+k+l+g)==4) ans-=f[j*b[s[0]]][k*b[s[1]]][l*b[s[2]]][g*b[s[3]]]*4;
    		}
    		else
    		if(d==2)
    		{
    			for(int j=0;j<=1;j++)
    				for(int k=0;k<=1;k++)
    					for(int l=0;l<=1;l++)
    						for(int g=0;g<=1;g++)
    							if((j+k+l+g)==2)
    							{
    								ans+=f[j*b[s[0]]][k*b[s[1]]][l*b[s[2]]][g*b[s[3]]];
    							}
    							else
    							if((j+k+l+g)==3)
    							{
    								ans-=f[j*b[s[0]]][k*b[s[1]]][l*b[s[2]]][g*b[s[3]]]*3;
    							}
    							else
    							if((j+k+l+g)==4)
    							{
    								ans+=f[j*b[s[0]]][k*b[s[1]]][l*b[s[2]]][g*b[s[3]]]*6;
    							}
    		}
    		else
    		if(d==1)
    		{
    			for(int j=0;j<=1;j++)
    				for(int k=0;k<=1;k++)
    					for(int l=0;l<=1;l++)
    						for(int g=0;g<=1;g++)
    							if((j+k+l+g)>=3)
    								if((j+k+l+g)%2) ans+=f[j*b[s[0]]][k*b[s[1]]][l*b[s[2]]][g*b[s[3]]];
    									else ans-=f[j*b[s[0]]][k*b[s[1]]][l*b[s[2]]][g*b[s[3]]]*4;
    		}
    		else
    		if(d==4)
    		{
    			for(int j=0;j<=1;j++)
    				for(int k=0;k<=1;k++)
    					for(int l=0;l<=1;l++)
    						for(int g=0;g<=1;g++)
    							if((j+k+l+g)>=0)
    								if(!((j+k+l+g)%2)) ans+=f[j*b[s[0]]][k*b[s[1]]][l*b[s[2]]][g*b[s[3]]];
    									else ans-=f[j*b[s[0]]][k*b[s[1]]][l*b[s[2]]][g*b[s[3]]];
    		}
    		for(int j=0;j<=1;j++)
    			for(int k=0;k<=1;k++) 
    				for(int l=0;l<=1;l++)
    					for(int g=0;g<=1;g++)
    						f[j*b[s[0]]][k*b[s[1]]][l*b[s[2]]][g*b[s[3]]]++;
    	}
    	printf("%d\n",ans);
    }
    
    
    
    posted @ 2018-05-08 15:40  无尽的蓝黄  阅读(128)  评论(0编辑  收藏  举报