(2019 GDUT Rating Contest #III)C. Team Tic Tac Toe

传送门

题目大意:

一群牛玩游戏(没错,你没听错,就是一群牛),每个牛有自己的字母代号,他们把字母填在一个九宫格里,像这样
像这样
他们如果一头牛自己连成了三点一线,那么他就赢了,或者两头牛合作连成了三点一线,那么他们也赢了,给一个九宫格给你,问有多少只队伍赢了?

题目分析:

相信绝大部分一眼看到就有想法,只是觉得麻烦(没错,这题就是考验代码量的题)。
其实队伍赢无非就8种情况:Ι Ι Ι,三 和 X。每种情况又分3种,以 1 2 3 为例,①1和2相等,②1和3相等,③2和3相等。
直接把每种情况列出来就行了(泪)。
注意:要判重,即A和C组队和C和A组队是一样的。这里我用了个二维数组来标记,保证字典序小的在前面,这样p[A][C],而不是p[C][A],这样就保证不会重复了。

代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
typedef pair<int,int> P;
const int maxn = 27;
char map[maxn][maxn];
int cnt[maxn];
P vis[10*maxn];
int ans1=0,ans2=0;
bool cmp(P x,P y){
	if(x.first==y.first) return x.second<y.second;
	return x.first<y.first;
}
int main(){
	for(int i=0;i<3;i++) scanf("%s",map[i]);
	int count=0;
	for(int i=0;i<3;i++){
		if(map[i][0]==map[i][1]&&map[i][1]==map[i][2]){
			if(cnt[map[i][0]-'a']==0){
				cnt[map[i][0]-'a']++;
				ans1++;
			}
		}
		else if(map[i][1]==map[i][0]||map[i][1]==map[i][2]||map[i][0]==map[i][2]){
			int a=map[i][0]-'a',b=map[i][1]-'a',c=map[i][2]-'a';
			if(a>b) swap(a,b);
			if(b>c) swap(a,c);
			if(a>b) swap(a,b);
			vis[count].first=a;vis[count].second=b;
			count++;
		}
	}
	for(int i=0;i<3;i++){
		if(map[0][i]==map[1][i]&&map[1][i]==map[2][i]){
			if(cnt[map[0][i]-'a']==0){
				cnt[map[0][i]-'a']++;
				ans1++;
			}
		}
		else if(map[1][i]==map[0][i]||map[1][i]==map[2][i]||map[0][i]==map[2][i]){
			int a=map[0][i]-'a',b=map[1][i]-'a',c=map[2][i]-'a';
			if(a>b) swap(a,b);
			if(b>c) swap(a,c);
			if(a>b) swap(a,b);
			vis[count].first=a;vis[count].second=b;
			count++;
		}
	}
	if(map[0][0]==map[1][1]&&map[0][0]==map[2][2]){
		if(cnt[map[0][0]-'a']==0){
			cnt[map[0][0]-'a']++;
			ans1++;
		}
	}
	else if(map[1][1]==map[0][0]||map[1][1]==map[2][2]||map[0][0]==map[2][2]){
		int a=map[0][0]-'a',b=map[1][1]-'a',c=map[2][2]-'a';
			if(a>b) swap(a,b);
			if(b>c) swap(a,c);
			if(a>b) swap(a,b);
			vis[count].first=a;vis[count].second=b;
		count++;		
	}
	if(map[0][2]==map[1][1]&&map[0][2]==map[2][0]){
		if(cnt[map[0][2]-'a']==0){
			cnt[map[0][2]-'a']++;
			ans1++;
		}
	}
	else if(map[1][1]==map[0][2]||map[1][1]==map[2][0]||map[0][2]==map[2][0]){
		int a=map[0][2]-'a',b=map[1][1]-'a',c=map[2][0]-'a';
			if(a>b) swap(a,b);
			if(b>c) swap(a,c);
			if(a>b) swap(a,b);
			vis[count].first=a;vis[count].second=b;
		count++;		
	}
	sort(vis,vis+count,cmp);
	ans2=count;
	for(int i=0;i<count-1;i++){
		if(vis[i].first==vis[i+1].first&&vis[i].second==vis[i+1].second) ans2--;
	}
	cout<<ans1<<endl<<ans2<<endl; 
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值