Educational Codeforces Round 37

本文解析了七道编程挑战题,包括水流花园、茶水排队等,涉及算法设计、数据结构应用及优化技巧。

A - Water The Garden

/*
    给出一排格子,告诉你一些格子上有水,会往两边流动,问流满全部格子需要的时间
*/
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
int main(){
    int T,n,m,a[210],d[210],ans;
    scanf("%d",&T);
    while(T--){
        ans=0;
        scanf("%d%d",&n,&m);
        memset(d,0x3f,sizeof(d));
        for(int i=1;i<=m;i++)scanf("%d",&a[i]);
        for(int i=1;i<=n;i++){
        	for(int j=1;j<=m;j++){
        		d[i]=min(d[i],abs(i-a[j])+1);
        	}ans=max(ans,d[i]);
        }    
        printf("%d\n",ans);
    }return 0;
}

B - Tea Queue

/*
    告诉你n个人来打水的时间和等待到的最迟时间,来的时间相同的话编号小的排前面
    问每个人取到水的时间,如果没取到水,则输出0
*/
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=5010; 
int T,n,l[N],r[N],ans[N];
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d%d",&l[i],&r[i]);
        int nowt=0;
		for(int i=1;i<=n;i++){
			if(nowt>r[i]){ans[i]=0;continue;}
        	if(l[i]>=nowt)ans[i]=l[i],nowt=l[i]+1;
			else ans[i]=nowt,nowt++; 
        }for(int i=1;i<=n;i++)printf("%d%c",ans[i],i==n?'\n':' ');
    }return 0;
}

C - Swap Adjacent Elements

/*
    告诉你一个a序列,和一个s序列,s序列为1表示这个位置的a序列可以和下一个互换,
    问能否通过随意交换可互换元素将a序列排序
*/
#include <cstdio>
#include <algorithm>
using namespace std;
int n,a[200010];
char s[200010];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    scanf("%s",s+1);s[n]='0';
    for(int i=1;i<n;i++){
        if(s[i]=='1'){
            for(int j=i;j<=n;j++){
                if(s[j]=='0'){
                    sort(a+i,a+j+1);
                    i=j;
                    break;
                }
            }
        }
    }
    int flag=1;
    for(int i=1;i<n;i++){
        if(a[i]>a[i+1]){puts("NO");flag=0;break;}
    }if(flag)puts("YES");
    return 0;
}

D - Tanks

/*
    题目大意:给出N个容量无限的桶,每个桶中开始都有一些水,给出一个大小为K的勺子,
    问你能否通过N+5次以内的勺水操作(从一个桶到另一个桶),使得最后能有一个桶中的
    水为V
    题解:我们将所有的桶中的水量对K取模,如果这些值能够取一些相加取模后得到V%K,
    说明答案可行,我们可以用01背包解决这个问题,对于路径输出,我们在做dp的时候记录路径,
    表示这个位置是答案的组成部分,那么根据是否是答案的组成部分,我们将桶分为两部分,
    对于处于同个部分的桶,我们把水全都倒进一个桶中,
    那么最后只要在这两个桶相互倒就可以得到答案
*/
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN=5010;
int N,K,V,S,a[MAXN];
bool dp[MAXN][MAXN],pre[MAXN][MAXN];
vector<int> vc[2];
void Solve(){
    for(int i=1;i<=N;i++)S+=a[i];
    if(S<V){puts("NO");return;}
    dp[0][0]=1;
    for(int i=1;i<=N;i++){
        int x=a[i]%K;
        for(int j=0;j<K;j++)if(dp[i-1][j]){
            dp[i][j]=1; pre[i][j]=0;
            dp[i][(j+x)%K]=1; pre[i][(j+x)%K]=1;
        }
    }if(!dp[N][V%K]){puts("NO");return;}
    int v=V%K;
    for(int i=N;i>0;i--){
        int x=a[i]%K;
        if(pre[i][v]){
            vc[1].push_back(i);
            v=(v-x+K)%K;
        }else vc[0].push_back(i);
    }
    puts("YES");
    sort(vc[0].begin(),vc[0].end());
    sort(vc[1].begin(),vc[1].end());
    for(int k=0;k<2;k++)if(vc[k].size()){
        for(int i=1;i<vc[k].size();i++)printf("%d %d %d\n",1000000000,vc[k][i],vc[k][0]);
    }
    int x0,x1,s=0;
    for(int i=0;i<vc[1].size();i++)s+=a[vc[1][i]];
    if(!vc[0].size())x1=vc[1][0],x0=vc[1][1];
    else if(!vc[1].size())x1=vc[0][1],x0=vc[0][0];
    else x1=vc[1][0],x0=vc[0][0];
    if(s<V)printf("%d %d %d\n",(V-s)/K,x0,x1);
    if(s>V)printf("%d %d %d\n",(s-V)/K,x1,x0);
}
int main(){
    scanf("%d%d%d",&N,&K,&V);
    for(int i=1;i<=N;i++)scanf("%d",&a[i]);
    Solve(); 
    return 0;
}

E - Connected Components?

/*
    题目大意:给出一张图,求补图的连通块和其大小
    题解:搜索的理论复杂度O(n^2),显然不行,
    bfs的时候对于已经归入其余连通块的点用并查集进行段无效信息处理,减少搜索树的分支,
    显然经过这样的处理搜索分支的数量下降得非常快,就能顺利解决此题了
*/
#include <cstdio>
#include <algorithm>
#include <queue> 
using namespace std;
const int N=200010;
int f[N],n,m,vis[N],ans,cnt[N];
vector<int> v[N];
int sf(int x){return f[x]==x?x:f[x]=sf(f[x]);}
void bfs(int st){
    queue<int> q;
    q.push(st);
    cnt[++ans]=1;
    while(q.size()){
        int x=q.front();q.pop();f[x]=sf(x+1);
        for(int i=0;i<v[x].size();i++)vis[v[x][i]]=x;
        for(int i=sf(1);i<=n;i=sf(i+1))if(vis[i]!=x){
            cnt[ans]++;
            f[i]=sf(i+1);
            q.push(i);
        }
    }
}
int main(){
    while(~scanf("%d%d",&n,&m)){
        ans=0;
        while(m--){
            int x,y;
            scanf("%d%d",&x,&y);
            v[x].push_back(y);
            v[y].push_back(x);
        }
        for(int i=1;i<=n+1;i++)f[i]=i;
        for(int i=1;i<=n;i=sf(i+1))bfs(i);
        printf("%d\n",ans);
        sort(cnt+1,cnt+ans+1);
        for(int i=1;i<=ans;i++)printf("%d%c",cnt[i],i==ans?'\n':' ');
    }return 0;
}

F - SUM and REPLACE

/*
    题目大意:给出一个序列,要求维护区间求和,和区间修改操作,
    修改操作是将区间中每个数变为其约数个数
    题解:我们计算一下约数个数发现,D(1)=1,D(2)=2,如果一个区间全是这样的数字的话
    我们就不需要对这个区间进行修改,所以我们只要暴力改数值,当发现一个区间的最大值是1或2时
    我们就停止往下修改
*/
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=1000010,M=2000010;
int p[N];
namespace Segment_Tree{
    int tot;
    struct node{int l,r,a,b;LL mx,val;}T[M];
    void build(int,int);
    void Initialize(int n){
        tot=0;
        build(1,n);
    } 
    void up(int x){
        T[x].val=T[T[x].l].val+T[T[x].r].val;
        T[x].mx=max(T[T[x].l].mx,T[T[x].r].mx);
    }
    void build(int l,int r){
        int x=++tot;
        T[x].a=l;T[x].b=r;T[x].l=T[x].r=T[x].val=T[x].mx=0;
        if(l==r){scanf("%lld",&T[x].val);T[x].mx=T[x].val;return;}
        int mid=(l+r)>>1;
        T[x].l=tot+1;build(l,mid);
        T[x].r=tot+1;build(mid+1,r);
        up(x);
    }
    void change(int x,int a,int b){
        if(T[x].mx==1||T[x].mx==2)return;
        if(T[x].a==T[x].b){T[x].mx=T[x].val=p[T[x].val];return;}
        int mid=(T[x].a+T[x].b)>>1;
        if(mid>=a&&T[x].l)change(T[x].l,a,b);
        if(mid<b&&T[x].r)change(T[x].r,a,b);
        up(x);
    }
    LL query(int x,int a,int b){
        if(T[x].a>=a&&T[x].b<=b)return T[x].val;
        int mid=(T[x].a+T[x].b)>>1; LL res=0;
        if(mid>=a&&T[x].l)res+=query(T[x].l,a,b);
        if(mid<b&&T[x].r)res+=query(T[x].r,a,b); 
        return res;
    } 
}
int n,m,t,l,r;
int main(){
    for(int i=1;i<=1000000;i++){
        for(int j=i;j<=1000000;j+=i)p[j]++;
    }
    scanf("%d%d",&n,&m);
    Segment_Tree::Initialize(n);
    while(m--){
        scanf("%d%d%d",&t,&l,&r);
        if(t==1)Segment_Tree::change(1,l,r);
        else printf("%lld\n",Segment_Tree::query(1,l,r));
    }return 0;
}

G - List Of Integers

/*
    题目大意:求出比x大的和p互质的第k大的数
    题解:我们二分答案,将题目转化为判定区间内和一个数互质的数是否大于k
    求区间内和一个数互质的数的个数我们可以用容斥来解决,将这个数的约数筛选出来,
    然后容斥区间内约数个数出现的次数即可
*/
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=10000010;
typedef long long LL;
#define pw(x) (1LL<<x)
int T;
LL x,y,k,p;
LL cal(LL x,vector<LL> &p){
    LL res=0;
    int n=p.size();
    for(int i=0;i<pw(n);i++){
        LL t=1,f=1;
        for(int j=0;j<n;j++)if(i>>j&1)t*=p[j],f*=-1;
        res+=f*(x/t);
    }return res;
}
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%lld%lld%lld",&x,&p,&k);
        vector<LL> f;
        for(LL i=2;i*i<=p;i++)if(p%i==0){
            f.push_back(i);
            while(p%i==0)p/=i;
        }
        if(p>1)f.push_back(p);
        k+=cal(x,f);
        LL l=1LL,r=1000000000000LL,ans;
        while(l<=r){
            LL mid=(l+r)/2;
            if(cal(mid,f)>=k)ans=mid,r=mid-1;
            else l=mid+1;
        }printf("%lld\n",ans);
    }return 0;
}

 

转载于:https://www.cnblogs.com/forever97/p/edu37.html

标题SpringBoot智能在线预约挂号系统研究AI更换标题第1章引言介绍智能在线预约挂号系统的研究背景、意义、国内外研究现状及论文创新点。1.1研究背景与意义阐述智能在线预约挂号系统对提升医疗服务效率的重要性。1.2国内外研究现状分析国内外智能在线预约挂号系统的研究与应用情况。1.3研究方法及创新点概述本文采用的技术路线、研究方法及主要创新点。第2章相关理论总结智能在线预约挂号系统相关理论,包括系统架构、开发技术等。2.1系统架构设计理论介绍系统架构设计的基本原则常用方法。2.2SpringBoot开发框架理论阐述SpringBoot框架的特点、优势及其在系统开发中的应用。2.3数据库设计与管理理论介绍数据库设计原则、数据模型及数据库管理系统。2.4网络安全与数据保护理论讨论网络安全威胁、数据保护技术及其在系统中的应用。第3章SpringBoot智能在线预约挂号系统设计详细介绍系统的设计方案,包括功能模块划分、数据库设计等。3.1系统功能模块设计划分系统功能模块,如用户管理、挂号管理、医生排班等。3.2数据库设计与实现设计数据库表结构,确定字段类型、主键及外键关系。3.3用户界面设计设计用户友好的界面,提升用户体验。3.4系统安全设计阐述系统安全策略,包括用户认证、数据加密等。第4章系统实现与测试介绍系统的实现过程,包括编码、测试及优化等。4.1系统编码实现采用SpringBoot框架进行系统编码实现。4.2系统测试方法介绍系统测试的方法、步骤及测试用例设计。4.3系统性能测试与分析对系统进行性能测试,分析测试结果并提出优化建议。4.4系统优化与改进根据测试结果对系统进行优化改进,提升系统性能。第5章研究结果呈现系统实现后的效果,包括功能实现、性能提升等。5.1系统功能实现效果展示系统各功能模块的实现效果,如挂号成功界面等。5.2系统性能提升效果对比优化前后的系统性能
在金融行业中,对信用风险的判断是核心环节之一,其结果对机构的信贷政策风险控制策略有直接影响。本文将围绕如何借助机器学习方法,尤其是Sklearn工具包,建立用于判断信用状况的预测系统。文中将涵盖逻辑回归、支持向量机等常见方法,并通过实际操作流程进行说明。 一、机器学习基本概念 机器学习属于人工智能的子领域,其基本理念是通过数据自动学习规律,而非依赖人工设定规则。在信贷分析中,该技术可用于挖掘历史数据中的潜在规律,进而对未来的信用表现进行预测。 二、Sklearn工具包概述 Sklearn(Scikit-learn)是Python语言中广泛使用的机器学习模块,提供多种数据处理建模功能。它简化了数据清洗、特征提取、模型构建、验证与优化等流程,是数据科学项目中的常用工具。 三、逻辑回归模型 逻辑回归是一种常用于分类任务的线性模型,特别适用于二类问题。在信用评估中,该模型可用于判断借款人是否可能违约。其通过逻辑函数将输出映射为0到1之间的概率值,从而表示违约的可能性。 四、支持向量机模型 支持向量机是一种用于监督学习的算法,适用于数据维度高、样本量小的情况。在信用分析中,该方法能够通过寻找最佳分割面,区分违约与非违约客户。通过选用不同核函数,可应对复杂的非线性关系,提升预测精度。 五、数据预处理步骤 在建模前,需对原始数据进行清理与转换,包括处理缺失值、识别异常点、标准化数值、筛选有效特征等。对于信用评分,常见的输入变量包括收入水平、负债比例、信用历史记录、职业稳定性等。预处理有助于减少噪声干扰,增强模型的适应性。 六、模型构建与验证 借助Sklearn,可以将数据集划分为训练集测试集,并通过交叉验证调整参数以提升模型性能。常用评估指标包括准确率、召回率、F1值以及AUC-ROC曲线。在处理不平衡数据时,更应关注模型的召回率与特异性。 七、集成学习方法 为提升模型预测能力,可采用集成策略,如结合多个模型的预测结果。这有助于降低单一模型的偏差与方差,增强整体预测的稳定性与准确性。 综上,基于机器学习的信用评估系统可通过Sklearn中的多种算法,结合合理的数据处理与模型优化,实现对借款人信用状况的精准判断。在实际应用中,需持续调整模型以适应市场变化,保障预测结果的长期有效性。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
### Codeforces Educational Round 26 比赛详情 Codeforces是一个面向全球程序员的比赛平台,其中Educational Rounds旨在帮助参与者提高算法技能并学习新技巧。对于具体的Educational Round 26而言,这类比赛通常具有如下特点: - **时间限制**:每道题目的解答需在规定时间内完成,一般为1秒。 - **内存限制**:程序运行所占用的最大内存量被限定,通常是256兆字节。 - 输入输出方式标准化,即通过标准输入读取数据并通过标准输出打印结果。 然而,关于Educational Round 26的具体题目细节并未直接提及于提供的参考资料中。为了提供更精确的信息,下面基于以往的教育轮次给出一些常见的题目类型及其解决方案思路[^1]。 ### 题目示例与解析 虽然无法确切描述Educational Round 26中的具体问题,但可以根据过往的经验推测可能涉及的问题类别以及解决这些问题的一般方法论。 #### 类型一:贪心策略的应用 考虑一个问题场景,在该场景下需要照亮一系列连续排列的对象。假设存在若干光源能够覆盖一定范围内的对象,则可以通过遍历整个序列,并利用贪心的思想决定何时放置新的光源以确保所有目标都被有效照射到。这种情况下,重要的是保持追踪当前最远可到达位置,并据此做出决策。 ```cpp #include <bits/stdc++.h> using namespace std; bool solve(vector<int>& a) { int maxReach = 0; for (size_t i = 0; i < a.size(); ++i) { if (maxReach < i && !a[i]) return false; if (a[i]) maxReach = max(maxReach, static_cast<int>(i) + a[i]); } return true; } ``` #### 类型二:栈结构处理匹配关系 另一个常见问题是涉及到成对出现元素之间的关联性判断,比如括号表达式的合法性验证。这里可以采用`<int>`类型的栈来记录左括号的位置索引;每当遇到右括号时就弹出最近一次压入栈底的那个数值作为配对依据,进而计算两者间的跨度长度累加至总数之中[^2]。 ```cpp #include <stack> long long calculateParens(const string& s) { stack<long long> positions; long long num = 0; for(long long i = 0 ; i<s.length() ;++i){ char c=s[i]; if(c=='('){ positions.push(i); }else{ if(!positions.empty()){ auto pos=positions.top(); positions.pop(); num+=i-pos; } } } return num; } ``` #### 类型三:特定模式下的枚举法 针对某些特殊条件约束下的计数类问题,如寻找符合条件的三位整数的数量。此时可通过列举所有可能性的方式逐一检验是否符合给定规则,从而统计满足要求的结果数目。例如求解形如\(abc\)形式且不含重复数字的正整数集合大小[^3]。 ```cpp vector<int> generateSpecialNumbers(int n) { vector<int> result; for (int i = 1; i <= min(n / 100, 9); ++i) for (int j = 0; j <= min((n - 100 * i) / 10, 9); ++j) for (int k = 0; k <= min(n % 10, 9); ++k) if ((100*i + 10*j + k)<=n&&!(i==0||j==0)) result.emplace_back(100*i+10*j+k); sort(begin(result), end(result)); return result; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值