T1:
判断两个集合A、B的关系,包括A包含B,B包含A,A和B完全相同或者A和B不满足以上所有的关系。
那么模拟一下。可以开一个hsh数组标记一下,对于一个A[i],将hsh[a[i]]–;对于一个B[i],将hsh[B[i]]++。这样有一个好处,就是如果这个数即存在于a数组,也存在于b数组,可以相互抵消。最后分四种情况特判一下就可以啦。
代码如下:
string SetPartialOrder::compareSets(vector <int> a, vector <int> b) {
int lena=a.size(),lenb=b.size();
bool pdmin=0,pdmax=0;
memset(hsh,0,sizeof(hsh));
for (int i=1;i<=lena;i++) hsh[a[i-1]]--;
for (int i=1;i<=lenb;i++) hsh[b[i-1]]++;
for (int i=1;i<=100;i++) {
if (hsh[i]<0) pdmin=1;
if (hsh[i]>0) pdmax=1;
}
if (pdmin==1&&pdmax==0) return "GREATER";
if (pdmin==1&&pdmax==1) return "INCOMPARABLE";
if (pdmin==0&&pdmax==1) return "LESS";
return "EQUAL";
}
T2
这题给定一个原串a和一个加密字符串b,你要根据这个加密规律求出某一加密串y的对应原串x。
如果不行就输出空串。
那么一看就只要简单的对于每一个b[i]做一个对于a[i]的映射就好了。
但是。。。我发现样例2死都过不去???
最后发现还有一个提示,没仔细看,突然秒懂,如果有25个字母已经一一对应了,对于最后一个加密字母,显然是可以求出它对应的原字母。
= =[汗]
那么既然如此,代码如下:
string SubstitutionCipher::decode(string a, string b, string y) {
memset(hsh,0,sizeof(hsh));
int lena=a.length(),lenb=b.length(),leny=y.length();
s="";
for (int i=1;i<=lena;i++) hsh[b[i-1]-'A'+1]=a[i-1]-'A'+1;
int sum=0;
for (int i=1;i<=26;i++) if (hsh[i]==0) sum++;
if (sum==1) {
for (int i=1;i<=26;i++) hsh1[hsh[i]]=1;
int x=0;
for (int i=1;i<=26;i++) if (!hsh1[i]) x=i;
for (int i=1;i<=26;i++) if (hsh[i]==0) hsh[i]=x;
}
for (int i=1;i<=leny;i++)
if (hsh[y[i-1]-'A'+1]==0) return "";
else s=s+(char)(hsh[y[i-1]-'A'+1]+'A'-1);
return s;
}
T3
这题题面极长。。。珂怕。
仔细一看,就是对于一个案件,侦探首先询问0,得出一串字符串,包含了他对于某一个人的怀疑程度,我们设为数组p。接下类侦探询问一个怀疑度最高的人x,如果这个人是凶手,就直接被抓滚粗;否则用这个人怀疑的程度来修正p,即对于每一个元素取
max(p[i],s[x][i])
m
a
x
(
p
[
i
]
,
s
[
x
]
[
i
]
)
。然后以此类推,直到抓到凶手。假设对于某一个人,如果他是凶手,抓到他的最小步数为ans[i]。那么我们要求的是(下标从0开始):
∑n−1i=0ans[i]
∑
i
=
0
n
−
1
a
n
s
[
i
]
接下来就讲讲题解。
我们发现人数n比较小,只有18。而这个大小如果直接暴搜又不那么合适。我们自然就会想到状压DP。对于每一个人作为凶手,都DP一遍。
具体的DP过程比较简单,每个状态先修正它的p数组,然后直接推下一状态。如果遇到凶手就修正答案,然后continue。
代码如下:
int dp(int x,vector <string> s){
memset(f,63,sizeof(f));
int ret=f[0]; f[1]=0;
for (int i=1;i<(1<<n);i++)
if (i%2==1){
memset(p,0,sizeof(p));
if ((i&(1<<x-1))) {ret=min(ret,f[i]); continue;}
for (int j=1;j<=n;j++)
if ((i&(1<<j-1))>0)
for (int k=2;k<=n;k++) p[k]=max(p[k],s[j-1][k-1]-'0');
int maxx=0;
for (int j=2;j<=n;j++) if (p[j]>maxx&&(i&(1<<j-1))==0) maxx=p[j];
for (int j=2;j<=n;j++)
if ((i&(1<<j-1))==0&&p[j]==maxx) {
f[i+(1<<j-1)]=min(f[i+(1<<j-1)],f[i]+1);
}
}
return ret;
}
int Tdetectived2::reveal(vector <string> s) {
n=s.size(); ans=0;
for (int i=2;i<=n;i++) {
ans+=(i-1)*dp(i,s);
}
return ans;
}
总结:
今天的这场TC比较水,但是因为我比较菜,T3调了半天,交的时候只剩下370分左右了。还是要增加代码能力,提升姿势水平啊= =
ps:因为我太懒(不会),没把代码写到class里面,而且比较糟乱,尽量还是不看代码,自己独立思考吧。。。
2018.7.24