57分找不到错因求助!!!我实在没找到问题
我想的方法是Trie树+模拟(不想用拓扑啊)
大致思路:(57分应该都是这么写的)
我们开一个small数组(字典序小的排在前面)
small[i][j]==1:当前字母i字典序小于j
small[i][j]==-1:当前字母i字典序大于j
small[i][j]==0:当前字母i,j之间顺序为确定
当需要small[i][j]=1时,small[i][j]却已被赋值为-1
这时发生冲突,就判断为不可行
而且,我看提交记录里有很多人和我都是57分,都是错同样的4个点,和Expected答案的差异都一样
我就搞不懂
然后我下了数据点4(n=30000,每个单词长度都为10)
Expected 是4630,我是4685(相信57pts的人情况都和我一样)
然后我又试着把数据点4的n值缩小,发现了一个惊人的事实
当n<=1300时,都是对的;
当n=1400时,我的输出:1218; Expected:1216
当n=1500时,我的输出:1304; Expected:1302
当n=1600时,我的输出:1392; Expected:1390
当n=1700时,我的输出:1483; Expected:1481
当n=1800时,我的输出:1574; Expected:1571
当n=1900时,我的输出:1636; Expected:1632
当n=2000时,我的输出:1540; Expected:1536
当n=2100时,我的输出:1596; Expected:1589
反正我就很懵
有没有哪位大佬帮我找下错啊
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+5;
int n,cnt,order[maxn][27],small[27][27],ans[30005];
string s[30005];
bool book[maxn],have[maxn][27];
inline void build(string s,int len){
int u=0;
for(int i=0;i<len;i++){
int son=s[i]-'a'+1;
if(!have[u][son]){
have[u][son]=1;
order[u][son]=++cnt;
}
u=order[u][son];
}
book[u]=1;
}
inline bool check(string s,int len){
for(int i=0;i<=26;i++) for(int j=0;j<=26;j++) small[i][j]=0;
int u=0;
for(int i=0;i<len;i++){
if(book[u]) return 0;
int son=s[i]-'a'+1;
for(int alpha=1;alpha<=26;alpha++){
if(alpha!=son&&have[u][alpha]){
// printf("small[%d][%d]=%d\n",son,alpha,small[son][alpha]);
if(small[son][alpha]==1) continue;
if(small[son][alpha]==-1) return 0;
if(small[son][alpha]==0){
small[son][alpha]=1;
small[alpha][son]=-1;
}
// printf(" --->small[%d][%d]=%d\n",son,alpha,small[son][alpha]);
}
}
u=order[u][son];
}
return 1;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
cin>>s[i];
build(s[i],s[i].size());
}
int tot=0;
for(int i=1;i<=n;i++){
bool p=check(s[i],s[i].size());
if(!p) continue;
ans[++tot]=i;
}
for(int i=1;i<=tot;i++){
cout<<s[ans[i]]<<"\n";
}printf("%d\n",tot);
return 0;
}
当然,如果你看不习惯这份代码
我这里还有另一位叫Darth_Che的大佬的57分代码。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#define rep(i,a,b) for(register int i=a;i<=b;i++)
#define maxn 500005
using namespace std;
int n,tri[maxn][26],vis[maxn],cnt,ans,ord[26][26],fir[maxn];
string s[maxn];
void insert(string s) {
int rt=0,len=s.size()-1;
rep(i,0,len) {
int id=s[i]-'a';
if(!tri[rt][id]) tri[rt][id]=++cnt;
rt=tri[rt][id];
}
vis[rt]++;
}
bool check(string s) {
int rt=0,len=s.size()-1;
rep(i,0,len) {
int id=s[i]-'a';
if(i!=len&&vis[tri[rt][id]]) return 0;
rep(j,0,25) {
if(tri[rt][j]&&id!=j) {
// cout<<id<<" "<<j<<" "<<ord[id][j]<<'\n';
if(!ord[id][j]) {
ord[id][j]=1;
ord[j][id]=2;
} else if(ord[id][j]==2) return 0;
}
}
rt=tri[rt][id];
}
return 1;
}
int main() {
ios::sync_with_stdio(false);
cin>>n;
rep(i,1,n) {
cin>>s[i];
insert(s[i]);
}
// cout<<'\n';
rep(i,1,n) {
memset(ord,0,sizeof(ord));
// cout<<s[i]<<" | ";
// cout<<check(s[i])<<" ";
// cout<<'\n';
// cout<<s[i]<<" ";
if(check(s[i])) ans++,fir[i]=1;
}
cout<<ans<<'\n';
rep(i,1,n) if(fir[i]) cout<<s[i]<<'\n';
return 0;
}