2020牛客暑期多校第八场G-Game SET(暴力假题)

博客园食用链接:https://www.cnblogs.com/lonely-wind-/p/13429549.html
题目大意:给你T组数据,每组n个字符串,你需要找出其中三个字符串使之能够构成一个集合,这个集合满足的条件为,对于字符串的每个性质,它要么全部一样,要么全部都不一样。如果不能找到输出-1,否则任意输出其位置。
字符串的构成如下:
[ n u m ] [ s h a p e ] [ s h a d i n g ] [ c o l o r ] [num][shape][shading ][color] [num][shape][shading][color],num性质包含 o n e , t w o , t h r e e one,two,three one,two,three,shape性质包含 d i a m o n d , s q u i g g l e , o v a l diamond, squiggle,oval diamond,squiggle,oval,shading的性质包含 s o l i d , s t r i p e d , o p e n solid, striped, open solid,striped,open,color的性质包含 r e d , g r e e n , p u r p l e red, green, purple red,green,purple
T ≤ 1000 , n ≤ 256 T\leq 1000,n\leq 256 T1000,n256

输入

3
3
[three][diamond][solid][red]
[two][*][solid][*]
[two][*][*][red]
5
[one][diamond][open][red]
[two][squiggle][solid][red]
[two][squiggle][*][red]
[two][diamond][solid][red]
[three][diamond][*][red]
6
[one][diamond][open][red]
[two][squiggle][*][green]
[two][squiggle][solid][green]
[two][diamond][solid][green]
[three][diamond][*][red]
[*][*][*][*]

输出
Case #1: -1
Case #2: 1 4 5
Case #3: 1 2 6

想的时候真的想用rand莽一发了,本来想用 n 2 n^2 n2的复杂的写的,结果我计算了一下, n ∗ n ∗ T ≈ 6 e 7 n*n*T\approx 6e7 nnT6e7。。。。要 O ( 1 ) O(1) O(1)查询啊?我枚举一下四个性质都直接爆了。。。怎么搞啊!!

后来讲题的时候。。。。 O ( n 3 ) O(n^3) O(n3)就可以直接过了,我????,实际上当n大于等于21的时候是一定有解的。。。当然,你也可以直接暴力模拟,我们这边就有个大模拟选手写了500来行的模拟过了。。。我是辣鸡QAQ。。
至于证明过程。。。Here,实际上我并打不开的链接

那么我们就可以直接暴力了。。。我们简化一些判断的条件,用string写起来会方便很多那么不合法的就是当两个性质记为 s 1 , s 2 s1,s2 s1,s2 s 1 = s 2 s1=s2 s1=s2 并且 s 3 ! = s 1 , s 3 ! = " ∗ " , s 1 ! = " ∗ " s3!=s1,s3!="*",s1!="*" s3!=s1s3!="",s1!="" 即:

int no(string s1,string s2,string s3)
{
	if (s1==s2 && s3!=s1 && s3!="*" && s1!="*") return 1;
	if (s1==s3 && s2!=s1 && s2!="*" && s1!="*") return 1;
	if (s2==s3 && s1!=s2 && s1!="*" && s2!="*") return 1;
	return 0; 
}

以下是AC代码:

#include <bits/stdc++.h>
using namespace std;

const int mac=1e3;
const int esp=1e3+10;

char s[mac][50];
int vis[300];

string ss[mac][6];

int no(string s1,string s2,string s3)
{
	if (s1==s2 && s3!=s1 && s3!="*" && s1!="*") return 1;
	if (s1==s3 && s2!=s1 && s2!="*" && s1!="*") return 1;
	if (s2==s3 && s1!=s2 && s1!="*" && s2!="*") return 1;
	return 0; 
}

int ok(int id1,int id2,int id3)
{
	int nb=0;
	for (int i=1; i<=4; i++){
		if (no(ss[id1][i],ss[id2][i],ss[id3][i])) return 0;
	}
	return 1;
}

int main(int argc, char const *argv[])
{
	int t;
	scanf ("%d",&t);
	for (int cse=1; cse<=t; cse++){
		int n;
		scanf ("%d",&n);
		for (int i=0; i<n; i++){
			scanf ("%s",s[i]);
			int len=strlen(s[i]);
			int cnt=1;
			ss[i][1]=ss[i][2]=ss[i][3]=ss[i][4]="";
			for (int j=0; j<len; j++){
				if (s[i][j]==']') {cnt++; continue;}
				else if (s[i][j]=='[') continue;
				ss[i][cnt]+=s[i][j];
			}
		}
		int mk=0;
		printf("Case #%d: ",cse);
		for (int i=0; i<n-2; i++){
			for (int j=i+1; j<n-1; j++){
				for (int k=j+1; k<n; k++){
					if (ok(i,j,k)){
						printf("%d %d %d\n",i+1,j+1,k+1);
						mk=1; break;
					}
				}
				if (mk) break;
			}
			if (mk) break;
		}
		if (!mk) printf("-1\n");
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值