C++小白训练第四天

C++小白训练第四天

以下为牛客挑战

今日收获

学习到两种遍历的方法
for (auto &z : a)	z 是引用(别名)	✅ 修改会写回原数组
for (auto z : a)	z 是值拷贝	❌ 修改只影响副本


在函数内部定义函数要调用自己时候直接self(self),

auto inner = [&](int x) -> void {   // & 表示按引用捕获外部所有变量
        cout << x << endl;
    };


字典树模板
const int N = 1e6 + 10;     // 总结点上限,按需调大
int son[N][26], idx = 0;    // son[p][c] 节点 p 的 c 号孩子;-1 表示空
bool isEnd[N];              // isEnd[p] 节点 p 是否是某个单词的结尾

void insert(const string &s) {
    int p = 0;              // 0 号节点是根
    for (auto &ch : s) {
        int u = ch - 'a';   // 0~25
        if (!son[p][u]) son[p][u] = ++idx; // 没有路就修一条
        p = son[p][u];      // 往下走
    }
    isEnd[p] = true;        // 标记单词结束
}

牛客周赛 Round 126

小红的好数组构造

C-小红的好数组构造_牛客周赛 Round 126

image-20260114091307251

6 2
1 1 4 5 1 4

这个我们可以想到一个条件就是,n-k的结果必须是偶数,因为这个是必要条件,如果不满足就不能构造成功,因为好数组需要满足去除完后是偶数。

对于其他的我们可以这样构造,前面n-k个是1,后面的就是2,3,4,5,6排下去就行了。

解题代码

#include<bits/stdc++.h>
#define int long long
#define lll __uint128_t
#define PII pair<int ,int>
#define endl '\n'
using namespace std;
#define yn(ans) printf("%s\n", (ans)?"Yes":"No");//快速打印
#define YN(ans) printf("%s\n", (ans)?"YES":"NO");
#define REP(i, e) for (int i = 0; i < (e); ++i)
#define REP1(i, s, e) for (int i = (s); i <=(e); ++i)
#define TESTS int t; cin >> t; while (t--)
#define TEST
const int N=2e5+10,M=1e3+10,mod=1e9+7;
int a[N],b[N],c[N],pre[N];

signed main(){

	std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n,k;
    cin>>n>>k;
    if((n-k)%2!=0){
        cout<<"-1"<<endl;
    }else{
        for(int i=0;i<n-k;i++){
            cout<<"1 ";
        }
        int m=1;
        for(int i=n-k;i<n;i++){
            cout<<++m<<" ";
        }
    }

	return 0;
}

小红的左看右看构造

D-小红的左看右看构造_牛客周赛 Round 126

image-20260114102325677

2 3 4
1 5
1 4 5
1 5 4 1

这个题画一个图就最好理解了

image-20260114102539851

如果最后的数不相同直接-1.

就是如果两个数组的长度加起来没有,那么长,直接在中间补齐最大值就行

解题代码

#include<bits/stdc++.h>
#define int long long
#define lll __uint128_t
#define PII pair<int ,int>
#define endl '\n'
using namespace std;
#define yn(ans) printf("%s\n", (ans)?"Yes":"No");//快速打印
#define YN(ans) printf("%s\n", (ans)?"YES":"NO");
#define REP(i, e) for (int i = 0; i < (e); ++i)
#define REP1(i, s, e) for (int i = (s); i <=(e); ++i)
#define TESTS int t; cin >> t; while (t--)
#define TEST
const int N=2e5+10,M=1e3+10,mod=1e9+7;


signed main(){

	std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n,x,y;
    cin>>x>>y>>n;
    vector<int>a(x),b(y);
    for (int i = 0; i < x; ++i) {
        cin>>a[i];
    }
    for (int i = 0; i < y; ++i) {
        cin>>b[i];
    }
    if(a.back()!=b.back()){
        cout<<"-1";
        return 0;
    }
    b.pop_back();//删除最后一个元素。
    reverse(b.begin(),b.end());
    while (a.size()+b.size()<n){
        a.emplace_back(a.back());
    }
    if(a.size()+b.size()>n){
        cout<<"-1";
        return 0;
    }
    for(auto &z: a){
        cout<<z<<" ";
    }
    for(auto &t: b){
        cout<<t<<" ";
    }

	return 0;
}

小红的完全平方数构造

E-小红的完全平方数构造_牛客周赛 Round 126

image-20260114110642567

1
114514
11451412335057984

这个题比较不容易去思考

我们可以枚举长度

image-20260114111256867

 int l=n*(int)pow(10,i);
        int r=n*(int)pow(10,i)+(int)pow(10,i)-1;
        int m=sqrt(r);
        
        if(m*m>=l){
            cout<<m*m<<endl;
            break;
        }

解题代码

#include<bits/stdc++.h>
#define int long long
#define lll __uint128_t
#define PII pair<int ,int>
#define endl '\n'
using namespace std;
#define yn(ans) printf("%s\n", (ans)?"Yes":"No");//快速打印
#define YN(ans) printf("%s\n", (ans)?"YES":"NO");
#define REP(i, e) for (int i = 0; i < (e); ++i)
#define REP1(i, s, e) for (int i = (s); i <=(e); ++i)
#define TESTS int t; cin >> t; while (t--)
#define TEST
const int N=2e5+10,M=1e3+10,mod=1e9+7;
int a[N],b[N],c[N],pre[N];



void solve(){
    int n;
    cin>>n;
    for(int i=1;i<=18;i++){
        int l=n*(int)pow(10,i);
        int r=n*(int)pow(10,i)+(int)pow(10,i)-1;
        int m=sqrt(r);
        
        if(m*m>=l){
            cout<<m*m<<endl;
            break;
        }
    }



};
signed main(){

	std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    TESTS{
        solve();
    };

	return 0;
}

小红的基环树染色构造

二分树涂色

F-小红的基环树染色构造_牛客周赛 Round 126

image-20260114122319973

4
1 2
2 3
3 1
3 4
1 2 3 1

基环树:对于一个包含 n 个点的简单连通图,如果其包含 n 条边,那么我们便称他为一个基环树。

这个相当于比树多了一条边

我们可以当成树的特殊情况来做。

image-20260114123109048

我们可以先把所有的按找两个颜色去图,因为这个是基环树,如果存在不满珠直接换成第3种方式。

解题代码

#include<bits/stdc++.h>
#define int long long
#define lll __uint128_t
#define PII pair<int ,int>
#define endl '\n'
using namespace std;
#define yn(ans) printf("%s\n", (ans)?"Yes":"No");//快速打印
#define YN(ans) printf("%s\n", (ans)?"YES":"NO");
#define REP(i, e) for (int i = 0; i < (e); ++i)
#define REP1(i, s, e) for (int i = (s); i <=(e); ++i)
#define TESTS int t; cin >> t; while (t--)
#define TEST
const int N=2e5+10,M=1e3+10,mod=1e9+7;
int a[N],b[N],c[N],pre[N];

signed main(){

	std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin>>n;
    vector<vector<int>>g(n+1);//图
    vector<pair<int,int>>e(n);
    for(int i=0,u,v;i<n;i++){
        cin>>u>>v;
        g[u].emplace_back(v);
        g[v].emplace_back(u);
        e[i]={u,v};//存边。
    }
    vector<int>ans(n+1);
    auto dfs=[&](auto && self,int u,int op)->void {
        ans[u]=op;
        for(auto & v : g[u]){
            if(ans[v]>0)continue;
            self(self,v,3-op);
        }
    };
    dfs(dfs,1,1);
    for(auto & [u,v] : e){
        if(ans[u]==ans[v]){
            ans[u]=3;
        }
    }
    for(int i=1;i<=n;i++){
        cout<<ans[i]<<" ";
    }
	return 0;
}

小红的字符串构造(hard)

字典树trie

G-小红的字符串构造(hard)_牛客周赛 Round 126

image-20260114140016797

image-20260114133128666

5 3
10
010
10101
1010
01
10101

这个是字典树,这个串就是那个字符串,01串就搞2个

这个是字符集的

const int N = 1e6 + 10;     // 总结点上限,按需调大
int son[N][26], idx = 0;    // son[p][c] 节点 p 的 c 号孩子;-1 表示空
bool isEnd[N];              // isEnd[p] 节点 p 是否是某个单词的结尾

void insert(const string &s) {
    int p = 0;              // 0 号节点是根
    for (auto &ch : s) {
        int u = ch - 'a';   // 0~25
        if (!son[p][u]) son[p][u] = ++idx; // 没有路就修一条
        p = son[p][u];      // 往下走
    }
    isEnd[p] = true;        // 标记单词结束
}
vector<array<int,2>>tre(m+2);
vector<int>edg(m+1);
void insert(const string &str) {
    int p = 0;
    for (char ch : str) {
        int u = ch - '0';
        if (!tre[p][u]) tre[p][u] = ++index;
        p = tre[p][u];
    }
    edg[p]++;               // 这个节点是几个串的结尾
}

最后再进行dfs

解题代码

#include<bits/stdc++.h>
#define int long long
#define lll __uint128_t
#define PII pair<int ,int>
#define endl '\n'
using namespace std;
#define yn(ans) printf("%s\n", (ans)?"Yes":"No");//快速打印
#define YN(ans) printf("%s\n", (ans)?"YES":"NO");
#define REP(i, e) for (int i = 0; i < (e); ++i)
#define REP1(i, s, e) for (int i = (s); i <=(e); ++i)
#define TESTS int t; cin >> t; while (t--)
#define TEST
const int N=2e5+10,M=1e3+10,mod=1e9+7;
int a[N],b[N],c[N],pre[N];

signed main(){

	std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n,k;
    cin>>n>>k;
    int m=0;
    vector<string>s(n);
    for(int i=0;i<n;i++){
        cin>>s[i];
        m+=s[i].size();
    }
    vector<array<int,2>>tre(m+2);
    vector<int>edg(m+1);
    int index=0;
    auto insert=[&](string s)->void{
        int p=0;
        for(auto & c:s){
            int u=c-'0';
            if(!tre[p][u])tre[p][u]=++index;
            p=tre[p][u];
        }
        edg[p]++;//终点。
    };
    for(int i=0;i<n;i++){
        insert(s[i]);
    }
    string ans;
    int sum=0;
    bool ok=0;

    auto dfs=[&](auto & self,int cur)->void {
        if(ok)return ;
        if(sum==k){
            ok=1;
            cout<<ans<<endl;
            return;
        }else if(sum>k){
            return;
        }
        if(tre[cur][0]){
            ans+='0';
            sum+=edg[tre[cur][0]];
            self(self,tre[cur][0]);
            ans.pop_back();
            sum-=edg[tre[cur][0]];
        }
        if(tre[cur][1]){
            ans+='1';
            sum+=edg[tre[cur][1]];
            self(self,tre[cur][1]);
            ans.pop_back();
            sum-=edg[tre[cur][1]];
        }
    };
    dfs(dfs,0);
    if(!ok){
        cout<<"-1"<<endl;
    }
	return 0;
}
posted @ 2026-01-14 14:51  Godjian  阅读(4)  评论(0)    收藏  举报