SMU winter week4

前言

牛客三场 pta三场 pta缺了一场 还没补完

补题主要补了牛客的题

天梯赛的题还要再补一补

牛客

2026牛客寒假算法基础集训营4

真白的幻觉

当时没搞懂

在十进制下,目前已知的最大乘法持续性是 11,达到这个值的最小数是 277777788888899(15 位,小于 1018),另一个数 277777899999999999(18 位,小于 1018)也具有乘法持续性 11,并且它的 f(x) 与前者不同。

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 0x3f3f3f3f3f
//#define modd 1e9+7
#define PII pair<int,int>

void solve() {
	cout << "27777789999999999 277777788888899";
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int lll=1;
//	cin>>lll;
	while(lll--){
		solve();
		// cout<<'\n';
	}
	return 0;
}

2026牛客寒假算法基础集训营5

智乃的果子

一开始写的优先队列没过

遵循哈夫曼树的核心规则(每次合并重量最小的两堆),保证总代价最小;

对同重量的多个堆做 "两两批量合并",奇数个同重量堆时,剩余 1 个堆和下一个最小堆合并,保证所有堆最终合并为 1 个,且终止条件(只剩 1 个堆)正确。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long

int mod = 1e9 + 7;

signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int n;
    cin >> n;
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
    for (int i = 1; i <= n; i++)
    {
        int c, w;
        cin >> c >> w;
        q.push({w, c});
    }
    int ans = 0;
    while (1)
    {
        auto u = q.top();
        q.pop();

        if (q.empty() && u.second == 1)
            break;

        int w = u.first, c = u.second;
        int k = c / 2;

        if (k)
        {
            int a = 2 * w % mod * (k % mod) % mod;
            ans = (ans + a) % mod;
            q.push({w * 2, k});
        }

        if (c & 1)
        {
            auto u2 = q.top();
            q.pop();
            ans = (ans + (w + u2.first) % mod) % mod;
            q.push({w + u2.first, 1});
            if (u2.second > 1)
                q.push({u2.first, u2.second - 1});
        }
    }
    cout << ans << endl;
}

智乃的最大子段和取模

将子段和取模问题可以转化为前缀和之差取模的问题。

对于每个新的前缀和,在已有的前缀和中寻找能使差值取模最大的那个,使用set来维护前缀和,使用了lower_bound ,通过检查邻近元素来确保找到最优解。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

#define ull unsigned long long
#define int long long
#define pii array<int,2>
#define endl "\n"

void solve() {
    int n, mod;
    cin >> n >> mod;
    vector<int> a(n+9), s(n+9);
    for (int i = 1; i <= n; i++) cin >> a[i];
    for (int i = 1; i <= n; i++) s[i] = (s[i-1]+a[i]) % mod;

    int ans = 0, L = 1, R = 1;
    auto cal = [&](int l, int r) {
        if ((s[r]-s[l-1]+mod)%mod > ans) {
            ans = (s[r]-s[l-1]+mod)%mod;
            L = l, R = r;
        }
    };

    set<pii> st;
    st.insert({0, 1});
    for (int i = 1; i <= n; i++) {
        for (int x = 0; x <= 2; x++) {
            auto it = st.lower_bound({s[i] - (mod-1) + x*mod, n+1});
            if (it == st.end()) --it;
            for (int j = 1; j <= 5; j++) {
                cal((*it)[1], i);
                if (it == st.begin()) it = prev(st.end());
                else --it;
            }
        }
        st.insert({s[i], i+1});
    }

    cout << L-1 << " " << R-1 << " " << ans << endl;
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    for (int i = 0; i < t; i++) {
        solve();
    }
    return 0;
}

2026牛客寒假算法基础集训营6

小L的三角尺

贪心 + 优先队列(大根堆)

每次都选择当前能获得最大收益的那一次打磨操作,这样就能在有限的 w 次打磨中,让总斜边长度减少得最多,从而得到最小的总和。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

#define ull unsigned long long
#define int long long
#define pii array<int,2>
#define endl "\n"

double dis(int x, int y) {
	return sqrtl(x*x+y*y);
}

void solve() {
	int n, w;
	cin >> n >> w;
	priority_queue<pair<double, pii>> pq;
	double ans = 0;
	for (int i = 1; i <= n; i++) {
		int x, y;
		cin >> x >> y;
		double d = dis(x,y) - dis(x,y-1);
		pii tmp = {x,y};
		pq.push(make_pair(d, tmp));
		ans += dis(x,y);
	}
	while (w--) {
		if (pq.empty()) break;
		auto [d, tmp] = pq.top();
		pq.pop();
		ans -= d;
		auto [x, y] = tmp;
		y--;
		if (y == 0) continue;
		
		d = dis(x,y) - dis(x,y-1);
		tmp = {x,y};
		pq.push(make_pair(d, tmp));
	}
	cout << fixed << setprecision(10) << ans << endl;
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t = 1;
	for (int i = 0; i < t; i++) {
		solve();
	}
	return 0;
}

小L的彩球

组合计数问题 用"隔板法" 模型

cpp 复制代码
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define mod 998244353
using namespace std;
int n,x,t,y;
int jc[1000009];
int jcinv[1000009];
int ksm(int x,int y)
{
    int res=1;
    while(y>0){
        if(y&1){
            res=(res*x)%mod;
        }
        x=(x*x)%mod;
        y/=2;
    }
    return res;
}
void inv()
{
    jc[0]=1;
    for(int i=1;i<=1000005;i++){
        jc[i]=jc[i-1]*i%mod;
    }
    jcinv[1000005]=ksm(jc[1000005],mod-2);
    for(int i=1000004;i>=0;i--){
        jcinv[i]=jcinv[i+1]*(i+1)%mod;
    }
}
int C(int x,int y)
{
    if(x<0||y<0||y>x) return 0;
    return jc[x]*jcinv[x-y]%mod*jcinv[y]%mod;
}
void solve()
{
    cin>>n>>x>>t;
    y=n-x;
    if(t==0){
        if(x==n||y==n)
        cout<<"1"<<endl;
        else
        cout<<"0"<<endl;
        return; 
    }
    int ans=1;
    if(t&1){
        int ptr=(t+1)/2;
        ans=ans*C(x-1,ptr-1)%mod*C(y-1,ptr-1)%mod;
        ans=ans*2%mod;
    }else{
        ans--;
        int ptr=t/2;
        ans=(ans+C(x-1,ptr-1)*C(y-1,ptr)%mod)%mod;
        ans=(ans+C(x-1,ptr)*C(y-1,ptr-1)%mod)%mod;
    }
    cout<<ans<<endl;
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int T;
    cin>>T;
    inv();
    while(T--)solve();
    return 0;
}

pta

估值一亿的AI核心代码

cpp 复制代码
#include <bits/stdc++.h>
 
using namespace std;
 
 
int judge(char c)
{  
    if((c>='A'&&c<='Z')||(c>='a'&&c<='z'))
        return 1;
    else if(c>='0'&&c<='9')
        return 2;
    else if(c==' ')
        return 0;
    else 
        return -1;
}
 
string AI(string ask)
{
    while(ask[0]==' ')
        ask.erase(ask.begin());
    while(ask[ask.size()-1]==' ')
        ask.erase(ask.end()-1);
    
    for(int i=0;i<ask.size();i++)
    {

        if(ask[i]>='A'&&ask[i]<='Z'&&ask[i]!='I')
            ask[i]+=32;
        if(ask[i]=='?')
            ask[i]='!';
        if(ask[i]==' ')
        {
            int j=i+1;
            while(ask[j]==' ') j++;
            ask.erase(ask.begin()+i+1,ask.begin()+j);
        }
    }
    for(int i=0;i<ask.size();i++)
    {
        if(i==0)
        {
            if(ask[i]=='I'&&(judge(ask[i+1])<=0||i+1==ask.size()))
                ask.replace(i,1,"you");
            else if(ask.substr(i,2)=="me"&&(judge(ask[i+2])<=0||i+2==ask.size()))
                ask.replace(i,2,"you");
            else if(ask.substr(i,7)=="can you"&&(judge(ask[i+7])<=0||i+7==ask.size()))
                ask.replace(i,7,"I can");
            else if(ask.substr(i,9)=="could you"&&(judge(ask[i+9])<=0||i+9==ask.size()))
                ask.replace(i,9,"I could");
        }
        if(judge(ask[i])<=0)
        {
            if(judge(ask[i+1])==1)
            {
                if(ask[i+1]=='I'&&(judge(ask[i+2])<=0||i+2==ask.size()))
                    ask.replace(i+1,1,"you");
                if(ask.substr(i+1,2)=="me"&&(judge(ask[i+3])<=0||i+3==ask.size()))
                    ask.replace(i+1,2,"you");
                if(ask.substr(i+1,7)=="can you"&&(judge(ask[i+8])<=0||i+8==ask.size()))
                    ask.replace(i+1,7,"I can");
                if(ask.substr(i+1,9)=="could you"&&(judge(ask[i+10])<=0||i+10==ask.size()))
                    ask.replace(i+1,9,"I could");
            }
        }
    }
 
    return ask;
}
 
int main()
{
    int n;
    string ask,ans;
    cin>>n;
    cin.get();
    while(n--)
    {
        getline(cin,ask);
        cout<<ask<<endl;
        ans=AI(ask);
        cout<<"AI: ";
        for(int i=0;i<ans.size();i++)
        {
            if(ans[i]==' '&&judge(ans[i+1])<=0)
                continue;
            else
                cout<<ans[i];
        }
        cout<<endl;
    }
    return 0;
}

病毒溯源

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

#define ull unsigned long long
#define int long long
#define pii array<int,2>
#define endl "\n"
vector<int> t[10010];
vector<int> ans, path;
void dfs(int rt){
	if(t[rt].size() == 0){
		if(path.size() > ans.size() ||(path < ans && path.size() == ans.size())) ans = path;
		return ;
	}
	
	for(int i = 0; i < t[rt].size(); i++){
		path.push_back(t[rt][i]);
		dfs(t[rt][i]);
		path.pop_back();
	}
	
}


void solve() {
	int N, rt;
	cin >> N;
	rt = (0 + N - 1) * N / 2;
	for(int i = 0; i < N; i++){
		int K;
		cin >> K;
		for(int j = 0; j < K; j++){
			int v;
			cin >> v;
			rt -= v;
			t[i].push_back(v);
		}
	}
	dfs(rt);
	cout << ans.size() + 1 << endl << rt;
	for(int i = 0; i < ans.size(); i++){
		cout << " " << ans[i];
	}
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t = 1;
	for (int i = 0; i < t; i++) {
		solve();
	}
	return 0;
}
相关推荐
zmzb01032 小时前
C++课后习题训练记录Day105
开发语言·c++·算法
闻缺陷则喜何志丹2 小时前
【拆位法】P8743 [蓝桥杯 2021 省 A] 异或数列|普及+
c++·蓝桥杯·位运算·拆位法
fpcc2 小时前
跟我学C++中级篇——Concepts的循环依赖
c++·模板和元编程
訫悦3 小时前
C++自带的set get语法(MSVC)
开发语言·c++
墨雪不会编程3 小时前
C++之【list详解篇一】如何玩好链表
c++·链表·list
柏木乃一4 小时前
Linux进程信号(2):信号产生part2
linux·运维·服务器·c++·信号处理·信号·异常
HAPPY酷4 小时前
C++ 成员指针(Pointer to Member)完全指南
java·c++·算法
Sunsets_Red4 小时前
浅谈随机化与模拟退火
java·c语言·c++·python·算法·c#·信息学竞赛
星火开发设计5 小时前
模板参数:类型参数与非类型参数的区别
java·开发语言·前端·数据库·c++·算法