河南萌新联赛2024第(二)场:南阳理工学院(ACDEFHIJ赛时加赛后补题)

I.重生之zbk要拿回属于他的一切(签到,没啥好说的)

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=1e6+10,mod=998244353;
int h[N],e[N],ne[N],idx;
int a[N],b[N],w[N];
map<int,int>mp;
int n,m,q;
vector<pair<int,int> >v[N];
void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;}
void solve(){
    cin>>n;
    string s;cin>>s;
    int ans=0;
    for(int i=0;i<s.size();i++){
        string ss=s.substr(i,5);
        if(ss=="chuan")ans++;
    }
    cout<<ans<<endl;
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int _;
    _=1;
    //cin>>_;
    while(_--)solve();
    return 0;
}

A.国际旅行(签到,但是被骗了一会儿想复杂了,无用代码已注释)

 

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=1e6+10,mod=998244353;
int h[N],e[N],ne[N],idx;
int a[N],b[N],w[N];
map<int,int>mp;
int n,m,q;
vector<pair<int,int> >v[N];
void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;}
void solve(){
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++){
        int x;cin>>x;
        //a[i]=x;
        b[i]=x;
    }
    sort(b+1,b+1+n);
    while(q--){
        int k;cin>>k;
        cout<<b[k]<<endl;
    }
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int _;
    _=1;
    //cin>>_;
    while(_--)solve();
    return 0;
}

F. 水灵灵的小学弟(签到,没啥含金量,要真是博弈论还算一个正常题)

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=1e6+10,mod=998244353;
int h[N],e[N],ne[N],idx;
int a[N],b[N],w[N];
map<int,int>mp;
int n,m,q;
vector<pair<int,int> >v[N];
void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;}
void solve(){
    cin>>n>>m;
    cout<<"DHY"<<endl;
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int _;
    //_=1;
    cin>>_;
    while(_--)solve();
    return 0;
}

 J.这是签到(简单,打表暴力或硬推到5阶行列式计算都行,我直接套板子了)

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=1e6+10,mod=998244353;
int h[N],e[N],ne[N],idx;
int n,m,q;
map<string,set<string> >mp;//名字
set<string>se,temp;
map<string,int>mp1;
int g[10][10],a[10][10];
void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;}
int det(int nn)
{
    int res = 1;
    for (int i = 1; i <= nn; ++i)
    {
        for (int j = i + 1; j <= nn; ++j)
        {
            while (g[j][i])
            {
                int div = g[i][i] / g[j][i];
                for (int k = i; k <= nn ; ++k) 
                {
                    g[i][k] = (g[i][k] - div * g[j][k] ); 
                    swap(g[i][k], g[j][k]);
                }
                res*=-1;
            }
        }
        res = res * g[i][i];
    }
    return res;
}
void solve(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>a[i][j];
    int ans=0x3f3f3f3f;
    if(m!=n)ans=0;
    for(int k=1;k<=min(n,m);k++){
        for(int i=1;i<=k;i++){
            for(int j=1;j<=k;j++){
                g[i][j]=a[i][j];
            }
        }
        ans=min(ans,det(k));
    }
    cout<<ans<<endl;
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int _;
    _=1;
    while(_--)solve();
    return 0;
}

 H.狼狼的备忘录(简单,stl应用,嵌套常数太大平时用的不太多,但赛时这么写一大堆出来ac还是很有成就感的,数据范围很小,所以可以随便瞎搞)

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=1e6+10,mod=998244353;
int h[N],e[N],ne[N],idx;
int n,m,q;
map<string,set<string> >mp;//名字
set<string>se,temp;
map<string,int>mp1;
int g[10][10];
void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;}
void solve(){
    cin>>n;
    while(n--){
        string s;cin>>s;
        se.insert(s);
        int cnt;cin>>cnt;
        for(int i=0;i<cnt;i++){
            string ss;cin>>ss;
            mp[s].insert(ss);
        }
    }
    for(auto it=se.begin();it!=se.end();it++){
        for(auto itt=mp[*it].begin();itt!=mp[*it].end();itt++){
            for(auto ittt=mp[*it].begin();ittt!=mp[*it].end();ittt++){
                string ss=*itt,sss=*ittt;
                if(ss!=sss){
                    if(sss.size()>ss.size()){
                        string ssss=sss.substr(sss.size()-ss.size());
                        if(ssss==ss){
                            mp1[ss]=1;
                        }
                    }
                }
            }
        }
        temp.clear();
        for(auto itt=mp[*it].begin();itt!=mp[*it].end();itt++){
            if(!mp1[*itt])temp.insert(*itt);
        }
        mp[*it]=temp;
        mp1.clear();
    }
    int ans=0;
    for(auto it=se.begin();it!=se.end();it++)ans++;
    cout<<ans<<endl;
    for(auto it=se.begin();it!=se.end();it++){
        cout<<*it<<' ';
        cout<<mp[*it].size()<<' ';
        for(auto itt=mp[*it].begin();itt!=mp[*it].end();itt++){
            cout<<*itt<<' ';
        }
        cout<<endl;
    }
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int _;
    _=1;
    //cin>>_;
    while(_--)solve();
    return 0;
}

 E.好字符(中等,找循环同构把一个字符串复制加到原来的后面循环遍历长度即可,本题关键在26个字母,在a中出现过的可以标记一下,然后遍历这些标记的字符,每次遍历时,把字符串a和b除这个字符外其他无关字符统一标记为一个特殊字符,再判断b是否能成为a的子串,用kmp即可,ps:题解中提到的字符串最小表示法没听说过,但朋友赛时就是用这个方法做出来了,我到洛谷一看是道蓝题板子,学会了再来分享给大家)

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=1e6+10,mod=998244353;
int n,m,q;
int ans=0;
map<char,int>mp,mp1,mp2;
int ne[2*N];
void solve(){
    cin>>n;
    string aa,bb;cin>>aa>>bb;
    for(int i=0;i<n;i++)if(!mp[aa[i]])mp[aa[i]]=1;
    aa=" "+aa+aa,bb=" "+bb;
    string a,b;
    for(int i=0;i<26;i++){
        if(mp[char('a'+i)]){
            a=aa;
            b=bb;
            for(int j=1;j<=2*n;j++)if(a[j]!=char('a'+i))a[j]='.';
            for(int j=1;j<=n;j++)if(b[j]!=char('a'+i))b[j]='.';
            for(int j=2,k=0;j<=n;j++){//i指针遍历模式串,j指针指向待匹配串
                while(k&&b[k+1]!=b[j])k=ne[k];//匹配失败,j指针回退
                if(b[j]==b[k+1])k++;//如果匹配成功,j指针后移一位,此时i与j指针指向的字符相同
                ne[j]=k;//那么此时在匹配串中,模式串中以i为下标的字符最长前缀最后一位下标为j
            }
            for(int j=1,k=0;j<=2*n;j++){
                while(k&&b[k+1]!=a[j])k=ne[k];//回退
                if(b[k+1]==a[j])k++;
                if(k==n){
                    ans++;
                    break;
                }
            }
        }
    }
    cout<<ans<<endl;
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int _;
    _=1;
    while(_--)solve();
    return 0;
}

 D.A*BBBB(中等,题目都说了有特殊性质&python高精都过不了当然不可能套c++高精的板子啦!yysy赛时我开的第一道题就是这个想用高精&int128混过去首wa一发,看到某队1min过这题直到比赛结束后我都仍在怀疑人生,很明显有我不知道的科技or板子能把这题水过去(FFT),言归正传,注意到b的每一位都相同,假设xx=b[0]-'0',b长度为m,xx与a的每一位相乘得到的结果相同记为C,最终答案是C向前偏移m位相加的结果,手动模拟一下即可知道,用前缀和维护每一位相加的结果)

#include<bits/stdc++.h>
#define int long long
#define ll long long
#define endl '\n'
#define pb push_back
using namespace std;
const ll N=2e6+10;
int s[N];
ll n,m;
vector<int> mul(vector<int> &A, int b)
{
    vector<int> C;
    int t = 0;
    for (int i = 0; i < A.size() || t; i ++ )
    {
        if (i < A.size()) t += A[i] * b;
        C.push_back(t % 10);
        t /= 10;
    }
    while (C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}
void solve(){
    string a,b;cin>>a>>b;
    if(a[0]=='0'||b[0]=='0'){
        cout<<0<<endl;
        return;
    }
    vector<int>A;
    for(int i=a.size()-1;i>=0;i--)A.pb(a[i]-'0');
    int xx=b[0]-'0';
    auto C=mul(A,xx);
    vector<int>ans;
    reverse(C.begin(),C.end());
    C.pb(0);
    reverse(C.begin(),C.end());
    int rem=0;
    n=C.size()-1,m=b.size();
    for(int i=1;i<=n;i++)s[i]=s[i-1]+C[i];
    for(int i=1;i<n+m;i++){
        int l=max(0ll,i-m),r=min(n,i);
        int x=rem+s[r]-s[l];
        ans.pb(x%10);
        rem=x/10;
    }
    while(rem){
        ans.pb(rem%10);
        rem/=10;
    }
    for(int i=ans.size()-1;i>=0;i--)cout<<ans[i];
    cout<<endl;
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    ll _;
    _=1;
    cin>>_;
    while(_--)solve();
    return 0;
}

 C.小w和大W的决斗(中等,算是博弈论板子题吧,sg函数基本上差不多)

#include<bits/stdc++.h>
using namespace std;
const int N=110;
int n,f[N];
int sg(int x){
    if(f[x]!=-1)return f[x];
    unordered_set<int> S;
    for(int i=1;i<=x;i++)S.insert(sg(x-i));
    for(int i=1;i<=x;i++){
        for(int j=1;j<=x;j++){
            if(i+j<x){
                S.insert(sg(i)^sg(j)^sg(x-i-j));
            }
        }
    }
    for(int i=0;;i++){
        if(!S.count(i)){
            return f[x]=i;
        }
    }
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n;
    int res=0;
    memset(f,-1,sizeof f);
    for(int i=0;i<n;i++){
        int x;cin>>x;
        res^=sg(x);
    }
    if(res)cout<<"w win\n";
    else cout<<"W win\n";
    return 0;
}

 总结:感觉还是有进步,这篇题解拖了比较久是因为补题时自己独立做的,遇到很多坑点,中途还补足了很多缺少的前置知识,题目难度适中,本蒟蒻每场大概出5~6题,赛后可以补1~3题,继续加油,没补完的后续会加上题解

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值