题解 P4596 [COCI2011-2012#5] RAZBIBRIGA

坑点有点多的暴力题。


解题思路:

观察本题,可以发现其实所有的首尾相同的单词都是“等价的”,在本题的要求中,其实并不在乎中间的字母。

由此想到可以用一个二维桶来记录所有“相同的”单词,然后枚举四个顶点的单词并往里面填。

时间复杂度为 O ( 1 ) O(1) O(1) ,是常数级的,这一点另一篇题解写得有些问题。

正如开头所说,这题有很多坑点,现列举如下:

  1. 读词的顺序

    原文中是这样说的:

     	水平单词只能从左往右读,竖直的单词只能从上往下读。四个角共用一个字母。 
    

    这就意味着在代码中必须严格数组的顺序。

  2. “重复的词”

    原文中写到:

     一个方案中不允许有同一个单词,两个方案不同是指它们所构成的正方形至少有一个字母不同。
    

    这也就意味着当有几条边中首位字母一样时会有词重复计算,这里可以用减去的方法来完善算法。

  3. 其他

    在代码中提到


代码:

#include<cstring>
#include<cstdio>
using namespace std;
int h[30][30],n;
long long ans;
char a[100000];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%s",a);
		h[a[0]-'A'][a[strlen(a)-1]-'A']++;
		//注意是大写的 
	}
	int k1,k2,k3,k4;
	for(int i=0;i<26;i++){
		for(int j=0;j<26;j++){
			k1=h[i][j];h[i][j]--;
			for(int k=0;k<26;k++){
				k2=h[j][k];h[j][k]--;
				for(int l=0;l<26;l++){
					/*这里有一个大坑 
					读英文单词全都是从上往下,从左往右的
					不可以写成(i,j)(j,k)(k,l)(l,i) 
					*/
					k3=h[l][k];h[l][k]--;
					k4=h[i][l];
					ans+=k1*k2*k3*k4;
					h[l][k]++;
				}
				h[j][k]++;
			}
			h[i][j]++;
		}
	}
	printf("%lld\n",ans);
	//注意long long 
	return 0;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值