2017-4-6校内训练

cf训练赛

 

A.题目大意:给出n个数,问能否选出若干个数,使得这些数的和为m的倍数。(n<=10^6,m<=10^3)

思路:用f[i][j]表示前i个数是否能选出若干个和模m为j的数,直接DP,当f[i][0]为true时直接返回,虽然看上去是O(nm),但我们可以发现,当n超过m时答案必为真,证明如下:每次加入一个数x,若x不能被前i-1个数表示,我们令f[i][x]=true;若x能被前i-1个数表示,则2x能被前i个数表示,以此类推,每次加入x,至少会有一个原来为false的被设为了true,否则说明我们找到了m的倍数。总复杂度O(m^2)。

#include<cstdio>
inline int read()
{
    int x;char c;
    while((c=getchar())<'0'||c>'9');
    for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=(x<<3)+(x<<1)+c-'0';
    return x;
}
#define MN 1000
int u[2][MN+5];
int main()
{
    int n,m,x,i;
    n=read();m=read();
    while(n--)
    {
        u[n&1][x=read()%m]=1;
        for(i=0;i<m;++i)if(u[n&1^1][i])u[n&1][i]=u[n&1][(i+x)%m]=1;
        if(u[n&1][0])return 0*puts("YES");
    }
    puts("NO");
}

 

B.题目大意:给出一个1~n的置换,要求构造一棵n个点的树,使得树上每条边两端点编号置换后得到的边仍然出现在树中。(n<=10^5)

思路:先把置换拆成若干个循环,如果有长度为1的循环,那么其他所有点连到这个点即可,否则只有所有循环长度均为偶数且存在长度为2的循环才可以构造,选出一个长度为2的循环,其他所有点根据在循环中位置的奇偶分别连向这个循环的两个点,最后把这两个点自己连起来即可。

#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
inline int read()
{
    int x;char c;
    while((c=getchar())<'0'||c>'9');
    for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=(x<<3)+(x<<1)+c-'0';
    return x;
}
#define MN 100000
int a[MN+5],u[MN+5],cnt;
vector<int> v[MN+5];
int main()
{
    int n=read(),i,j,s,s1=0,s2=0,o=0;
    for(i=1;i<=n;++i)a[i]=read();
    for(i=1;i<=n;++i)if(!u[i])
    {
        for(++cnt,j=i;!u[j];u[j]=1,j=a[j])v[cnt].push_back(j);
        s=v[cnt].size();
        if(s==1)s1=cnt;
        if(s==2)s2=cnt;
        o|=s&1;
    }
    if(!s1&&(o||!s2))return 0*puts("NO");
    puts("YES");
    for(i=1;i<=cnt;++i)
        if(s1)for(j=0;j<v[i].size();++j){if(i!=s1)printf("%d %d\n",v[i][j],v[s1][0]);}
        else if(i!=s2)for(j=0;j<v[i].size();++j)printf("%d %d\n",v[i][j],v[s2][j&1]);
    if(!s1)printf("%d %d\n",v[s2][0],v[s2][1]);
}

 

C.题目大意:你有n张图片,你一开始翻到第1张,每次从第i张切换到第i-1或第i+1张需要a的时间(1可以切换到n,n可以切换到1),每张图片的朝向可能不太对,如果碰见朝向不对的,你需要花b时间转过来,每次你碰见第一次看到的图片,你会花1时间看它,问在t时间内最多看多少张图片。(n<=500,000)

思路:只会有两种情况,一种先往左边翻,然后再翻到右边,另一种先翻到右边再翻到左边,若只考虑先翻右的(另一种同理),可以预处理出从第1张翻到左边每一张时的花费,从左往右枚举右端点,显然左端点也递增,拿两个指针直接统计即可,总复杂度O(n)。

#include<cstdio>
#include<algorithm>
using namespace std;
#define MN 500000
char g[MN+5];
int n,a,b,t,ans,f[MN+5];
void solve()
{
    int i,j,s;
    for(i=n;i--;)f[i]=f[i+1]+a+b*(g[i]=='w')+1;
    for(i=j=s=0;i<n;++i,s+=a)
    {
        s+=b*(g[i]=='w')+1;
        if(s>t)break;
        ans=max(ans,i+1);
        if(s+i*a<=t)
        {
            while(j<=i||s+f[j]+i*a>t)++j;
            ans=max(ans,i+1+n-j);
        }
    }
}
int main()
{
    scanf("%d%d%d%d%s",&n,&a,&b,&t,g);
    solve();
    for(int i=1;i<n-i;++i)swap(g[i],g[n-i]);
    solve();
    printf("%d",ans);
}

 

D.题目大意:一个1~n的排列一开始为1,2,3,…,n,支持两种操作:1.循环右移k位;2.交换当前第1个和第2个,第3个和第4个……保证n为偶数。(n<=1,000,000,操作数<=2,000,000)

思路:把排列编号为0~n-1,两种操作分别表示为x=(x+k)mod n,x=x xor 1,显然如果奇偶性相同,偏移量也相同,两种情况都算一下即可,复杂度O(n)。

#include<cstdio>
inline int read()
{
    int x,f=1;char c;
    while((c=getchar())<'0'||c>'9')if(c=='-')f=0;
    for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=(x<<3)+(x<<1)+c-'0';
    return f?x:-x;
}
#define MN 1000000
int ans[MN+5];
int main()
{
    int n=read(),i,t,x,s0=0,s1=1;
    for(i=read();i--;)
    {
        t=read();
        if(t==1)x=read(),s0=(s0+x)%n,s1=(s1+x)%n;
        else s0^=1,s1^=1;
    }
    for(i=1;i<=n;++i)ans[(i+(i&1?s0:s1-1)+n)%n]=i;
    for(i=1;i<=n;++i)printf("%d ",ans[i%n]);
}

 

E.题目大意:给出n个数ci和一个数k,问是否对于任意的x,若确定所有x%ci,则可确定x%k。(n,k,ci<=1,000,000)

思路:显然要确定x%k的条件为k|lcm(ci),筛法预处理后把ci和k分解质因数,对每个质因子统计一下即可。

#include<cstdio>
#include<algorithm>
using namespace std;
inline int read()
{
    int x;char c;
    while((c=getchar())<'0'||c>'9');
    for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=(x<<3)+(x<<1)+c-'0';
    return x;
}
#define MN 1000000
int f[MN+5],p[MN+5],pn,s[MN+5];
int main()
{
    int n,k,i,j,cnt;
    for(i=2;i<=MN;++i)
    {
        if(!f[i])f[i]=i,p[++pn]=i;
        for(j=1;i*p[j]<=MN;++j){f[i*p[j]]=p[j];if(i%p[j]==0)break;}
    }
    n=read();k=read();
    while(n--)for(i=read();i>1;)
    {
        for(j=f[i],cnt=0;f[i]==j;i/=j)++cnt;
        s[j]=max(s[j],cnt);
    }
    while(k>1)
    {
        for(j=f[k],cnt=0;f[k]==j;k/=j)++cnt;
        if(s[j]<cnt)return 0*puts("No");
    }
    puts("Yes");
}

 

转载于:https://www.cnblogs.com/ditoly/p/20170406C.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园建设方案旨在通过信息化手段提升教育、管理和服务水平,实现资源数字化、工作流程化、管理高效化和决策智能化。方案包括智慧校园信息化平台和安防平台的建设,涉及教学、科研、管理和服务等多个方面,以满足现代教育和培训需求。 技术服务要求强调了统一支撑平台的建设,包括数据标准、接口标准、代码标准和用户信息标准的统一制定。平台需满足信创和X86交叉适配要求,确保安全自主可控的系统开发环境。此外,方案还涵盖了用户中心系统、统一认证授权中心、统一工作流中心、统一智能报表中心等多个模块,以及数据共享中心、语音识别、移动服务终端等功能,以实现校园内外部信息的互联互通和资源共享。 智慧校园信息化平台的建设还包括了对教学管理、人事管理、公文管理、档案管理、即时通讯、会议管理、督办工作、资产管理等方面的数字化和自动化升级。这些模块的集成旨在提高工作效率,优化资源配置,加强监督管理,并通过移动应用等技术手段,实现随时随地的信息访问和业务处理。 安防平台的建设则侧重于校园安全,包括停车场管理、人脸识别测温、访客自助登记、视频监控等多个系统。这些系统的集成旨在提高校园的安全管理水平,实现对校园内外人员和车辆的有效监控和管理,确保校园环境的安全稳定。 最后,方案还提到了对固定资产的管理,包括购置、使用、归还、报废等全生命周期的管理,以及对网络设备、安防设备、服务器等硬件设施的配置和管理。通过这些措施,智慧校园建设方案旨在为校园提供一个安全、高效、便捷的学习和工作环境。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值