河南萌新联赛2024第(二)场:南阳理工学院

“好”字符
1.使用字符串哈希来解决问题。
2.我们模拟样例来解决问题
\(a=acabxb,b=eababf,把a中出现过的字符放进set里,便于后面的遍历\)\(令b=eababfeababf,这样相当于模拟了循环同构。然后在我们遍历set里的\)
\(字母时,比如遍历a,我们相当于令字符串中的a为1,其余为0,此时对应的01串\)
\(为b=010100010100,这是我们脑袋中想象的过程,实现的过程中只需要统计到\)
\(每个位置的字符串的对应哈希值,比如遍历到0,01,010,0101......的位置的哈希值\)
\(此时的a=101000,a有一个对应的哈希值,那么相当于在b上移动一个长度为n的区间,\)
\(然后看这段区间的字符串的哈希值是不是跟a的哈希值相当即可\)

#include <bits/stdc++.h>
//#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define x first
#define y second
#define all(v) v.begin(),v.end()
#define ull unsigned long long

ull P=131;
ull pm[2000005],hb[1000005],ha[2000005];
void brdkhash(string s,char c,ull *h)
{
    for(int i=1;i<s.size();i++) h[i]=h[i-1]*P+(s[i]==c);//对应位置字符串的哈希
}

ull getx(ull *h,int l,int r){
    return h[r]-h[l-1]*pm[r-l+1];//计算区间字符串的哈希
}



void solve()
{
    int n; cin>>n;
    string a,b; cin>>a>>b;
    set<char>se(all(a));
    
    a=' '+a+a;//起点设为1,方便计数
    b=' '+b;
    
    pm[0]=1;
    for(int i=1;i<=2000005;i++) pm[i]=P*pm[i-1];//方便计算
    
    
    
    int ans=0;
    for(auto t:se)
    {
        brdkhash(a,t,ha);
        brdkhash(b,t,hb);
        for(int i=1;i<=n;i++)
        {
            if(getx(ha,i,i+n-1)==getx(hb,1,n)){
                ans++;
                break;
            }
        }
        
    }
    cout<<ans;
    
    
}





signed main()
{
    ios::sync_with_stdio(0),cin.tie(0);
    int t=1;
    //cin>>t;
    while(t--) solve();
}

这是签到
套个算行列式的板子,然后算出所有的值比较即可,如果n和m不同,记得把最后的结果和0比较

#include <iostream>
using namespace std;

const int MAXN = 7;

int det(int a[MAXN][MAXN], int n) {
    int res = 0;
    if (n == 1) {
        return a[0][0];
    } else {
        for (int j = 0; j < n; j++) {
            int t[MAXN][MAXN];
            for (int i = 1; i < n; i++) {
                int k = 0;
                for (int p = 0; p < n; p++) {
                    if (p == j) {
                        continue;
                    }
                    t[i - 1][k++] = a[i][p];
                }
            }
            res += ((j % 2 == 1) ? -1 : 1) * a[0][j] * det(t, n - 1);
        }
    }
    return res;
}

int main() {
    ios::sync_with_stdio(0),cin.tie(0);
    int n,m;
    cin >> n>>m;
    int minn=1e9;
    if(n!=m) minn=min(n,m);
    else minn=n;
    int a[MAXN][MAXN];
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> a[i][j];
        }
    }

    int ans=1e9;
    for(int i=1;i<=minn;i++)
    {
        ans=min(det(a,i),ans);
    }
 if(n!=m)   cout<<min(ans,0);
    else cout<<ans;
    return 0;
}

狼狼的备忘录

1.多开几个map存对应信息即可。
我的错误数据

点击查看代码
in
20
l 6 02 02 2 02 02 2
l 8 8 8 8 2 62 13 31 3
e 9 0 91 0 0 60 91 60 2 44
e 9 69 2 1 44 2 91 66 1 70
l 9 7 27 27 3 1 3 7 80 81
l 9 2 1 13 7 2 10 02 3 92
e 9 0 15 3 5 5 15 91 09 44
l 7 2 50 4 5 98 31 98
l 3 26 7 3
e 6 7 5 0 62 65 91
l 8 80 0 4 0 2 2 0 13
l 9 19 13 02 2 1 4 19 26 02
l 10 7 39 7 9 22 22 26 2 90 4
e 7 65 2 36 0 34 57 9
e 8 13 02 09 91 73 5 36 62
l 9 75 0 10 8 76 7 82 8 34
l 7 34 0 19 80 6 4 7
e 5 4 2 5 7 2
e 7 4 02 69 7 07 20 2
l 4 8 2 1 63


out:
2
e 18 02 07 09 13 15 20 34 36 44 57 60 62 65 66 69 70 73 91
l 21 02 10 13 19 22 26 27 31 34 39 50 62 63 75 76 80 81 82 90 92 98

题解代码

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define x first
#define y second
#define all(v) v.begin(),v.end()

void solve()
{
    int n; cin>>n;
    map<string,set<string> >mp;//放答案
    map<string,vector<string> >fi;//放各自的星座信息
    map<string,int>che;//用来去重,实现规则A
    set<string>na;//存出现过的名字
    for(int i=0;i<n;i++)
    {
        string s; cin>>s;
         na.insert(s);
        int x;cin>>x;
        while(x--)
        {
            string sb;
            cin>>sb;
           
            fi[s].push_back(sb);
        }
        
    }
    //全部放完以后在去去后缀,不然会有那个样例的错误
    
    for(auto t:na)
    {
        che.clear();
        for(auto k:fi[t])
        {
            for(int i=1;i<k.size();i++)
            {
                string ss=k.substr(i);
                che[ss]=1;
            }
        }
        for(auto k:fi[t]) {
            if(che[k]!=1) mp[t].insert(k);
        }
        
    }

    cout<<mp.size()<<endl;
    for(auto t:mp)
    {
        cout<<t.first<<" ";
        cout<<t.second.size()<<" ";
        
        vector<string>ans;
        for(auto k:t.second)
        {
            ans.push_back(k);
        }
        
        cout<<ans[0];
    if(ans.size()>1)    for(int i=1;i<ans.size();i++) cout<<" "<<ans[i];
        cout<<endl;
    }
    
    
}


signed main()
{
    ios::sync_with_stdio(0),cin.tie(0);
    int t=1;
    //cin>>t;
    while(t--) solve();
}

lxy的通风报信
1.使用bfs寻找每一个\(*\) 到其他\(*\)的距离,然后使用最小生成树算法,即可得到答案
2.但是细节非常多,注意bfs中细节的处理。

#include <bits/stdc++.h>
//#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define x first
#define y second
#define all(v) v.begin(),v.end()
#define ull unsigned long long
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
map<pii,int>mp;//给每个点编号
int n,m,ans,cnt;
bool tmp;
char c[1005][1005];
int f[1000005];
typedef struct{
    int from;//起点
    int to;//终点
    int dis;//距离
}road;



//-------------------------------------
//最小生成树算法的一部分
bool cmp(road a,road b)
{
    return a.dis<b.dis;
}

int find(int x){
    return f[x]==x?x:f[x]=find(f[x]);
}
//--------------------------------------
vector<road>ve;//放哪个点到哪个点的序号,和它们之间的距离

void bfs(int xx,int yy)
{//bfs计算每个结点到其他结点的距离
    queue<pii>q;
    q.push({xx,yy});
    int start=mp[{xx,yy}];//该起点的位置
    int foot[1005][1005]={0};//记录步数

   while(!q.empty())
   {
        auto t=q.front();
        q.pop();
        for(int i=0;i<4;i++)
        {
            int a=t.x+dx[i],b=t.y+dy[i];
            if(a>=1&&a<=n&&b>=1&&b<=m&&c[a][b]!='#'&&foot[a][b]==0)
            {
                q.push({a,b});
                foot[a][b]=foot[t.x][t.y]+1;//记得放if外面,不然会死循环
                if(c[a][b]=='*') {
                    ve.push_back({start,mp[{a,b}],foot[a][b]});
                }
            }
            
        }
       
   }
    
    
}


signed main()
{
    ios::sync_with_stdio(0),cin.tie(0);
     cin>>n>>m;
   int id=1;
   for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++) {
        cin>>c[i][j];
        if(c[i][j]=='*')
        mp[{i,j}]=id++;
    }
    

   for(int i=1;i<=n;i++)
     {
         for(int j=1;j<=m;j++)
         {
             if(c[i][j]=='*') bfs(i,j);
         }
     }
//-----------------------------------------------
  //最小生成树算法 kruskal算法  
    sort(all(ve),cmp);
    
    for(int i=1;i<=1000005;i++) f[i]=i;
    
    for(int i=0;i<ve.size();++i){
		int fx=find(ve[i].from),fy=find(ve[i].to);
		if(fx==fy) continue;
		f[fy]=fx;
		ans+=ve[i].dis;
		++cnt;
		if(cnt==mp.size()-1){
            tmp=1;
            break;
        }
	}
    
    if(tmp) cout<<ans;
    else cout<<"No";
 //------------------------------------------  
    
}

posted on 2024-07-25 16:33  swj2529411658  阅读(48)  评论(0编辑  收藏  举报

导航