IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 文远知行杯广东工业大学第十六届程序设计竞赛ABEFHI(记录) -> 正文阅读

[C++知识库]文远知行杯广东工业大学第十六届程序设计竞赛ABEFHI(记录)

文远知行杯广东工业大学第十六届程序设计竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ大学ACM校赛新生赛是面向ACM/ICPC/CCPC/区域赛校队选手,巩固经典专题的编程比赛,ACM入门训练,大学ACM校队选拔比赛。icon-default.png?t=M276https://ac.nowcoder.com/acm/contest/30896


A.区间最大值

https://ac.nowcoder.com/acm/contest/30896/Aicon-default.png?t=M276https://ac.nowcoder.com/acm/contest/30896/A

由题目中的n%i容易想到整除分块,也就是n/i,再次发现由于我们按照n/i的值对数组进行分块,每一块的元素的n%i的余数都是递减的(很容易证明,因为n/i结果相等的区间,n不变而i递增,会导致n%i下降),然后每次我们对于每次询问去暴力遍历每一块的的左端点(最大值).取最大值即可.(建议学一学整除分块).

#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
using namespace std;
int arr[200005];
map<int,int>ma;
int main()
{
    int t,n,cnt=0;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d",&arr[i]);
    scanf("%d",&t);
    for(int i=0;i<n;i++)
    {
        if(!ma.count(arr[i]/t))
        {
            ma[arr[i]/t]=1;
            cnt++;
        }
    }
    printf("%d",cnt);
    return 0;
}

B.模块改造

https://ac.nowcoder.com/acm/contest/30896/Bicon-default.png?t=M276https://ac.nowcoder.com/acm/contest/30896/B

签到模拟.

#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
using namespace std;
void print(int st,int en)
{
    int sth,enh;
    sth=st/2;
    enh=en/2;
    if(sth<10)
        printf("0");
    printf("%d:",sth);
    if(st%2==0)
        printf("00");
    else
        printf("30");
    printf(" - ");
    if(enh<10)
        printf("0");
    printf("%d:",enh);
    if(en%2==0)
        printf("00");
    else
        printf("30");
    printf("\n");
}
int main()
{
    string str;
    int flag=0,st=-1,en=-1,cont=0;
    cin>>str;
    for(int i=0;i<str.size();i++)
    {
        if(cont==0&&str[i]=='1')//未开始
        {
            cont=1;
            flag=1;
            st=i,en=i+1;
        }
        else if(cont==1&&str[i]=='1')
        {
            en++;
        }
        if(cont==1&&str[i]=='0')
        {
            print(st,en);
            st=-1,en=-1;
            cont=0;
        }
    }
    if(st!=-1&&en!=-1)
        print(st,en),flag=1;
    if(flag==0)
        printf("00:00 - 00:00");
    return 0;
}

E.爬塔

https://ac.nowcoder.com/acm/contest/30896/Eicon-default.png?t=M276https://ac.nowcoder.com/acm/contest/30896/E我们可以用一个长度为10的set去存每对满足题目条件的区间左右的端点,set[i]中i的含义是区间的长度.这样记录自动排序后,用lower_bound去查找即可.

#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<vector>
#include <utility>
using namespace std;
set<pair<int,int>>se[12];
void solve()
{
    int l,r;
    scanf("%d%d",&l,&r);
    for(int i=10;i>=1;i--)
    {
        auto it=se[i].lower_bound({l,l});
        if(it->first>=l&&it->second<=r)
        {
            cout<<i<<"\n";
            return ;
        }
    }
    cout<<"0"<<"\n";
    return ;
}
int main()
{
    int n,m;
    string str;
    scanf("%d",&n);
    cin>>str;
    str="1"+str;
    for(int i=1;i<=n;i++)
    {
        int ans=1;
        for(int j=i;j<=min(n,i+9);j++)
        {
            if(str[j]=='1')
                ans++;
            else if(str[j]=='0')
                ans--;
            if(ans<=0)
                break;
            //cout<<i<<" "<<j<<" "<<ans<<"\n";
            if(ans==1)
            {
                se[j-i+1].insert({i,j});
                //cout<<i<<" "<<j<<"\n";
            }
        }  
    }
    scanf("%d",&m);
    while(m--)
        solve();
    return 0;
}

F.一个很大的数

登录—专业IT笔试面试备考平台_牛客网icon-default.png?t=M276https://ac.nowcoder.com/acm/contest/30896/F

?如图,我们可以将原有的每一种情况和新的情况相乘组合出新的情况,新的情况和老的情况不会重复,一起构成已有情况,继续循环下去即可.按照循环计算ans=ans+(ans*2*y)(y是每个素数的次数,乘以2是因为每次可以组成(1,k)和(k,1)两种组合).

#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#define int long long
using namespace std;
int qmi(int x,int y,int mod)
{
    int res=1;
    while(y)
    {
        if(y&1)
            res=res*x%mod;
        y>>=1;
        x=x*x%mod;
    }
    return res;
}
signed main()
{
    int t,n,x,y;
    scanf("%lld",&t);
    while(t--)
    {
        int ans=1;
        scanf("%lld",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld%lld",&x,&y);
            ans=((ans%1000000007+(ans*2%1000000007*y%1000000007))%1000000007);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

H.变换01串

登录—专业IT笔试面试备考平台_牛客网icon-default.png?t=M276https://ac.nowcoder.com/acm/contest/30896/H读题,其实题目说可以两个方向操作,只需要从一个方向进行即可,其实是一样的.用线段树的方法来进行区间操作.首先解决最初始的查询问题,查询时利用线段树,线段树维护每个区间的左右范围,左右端点的值,还有贡献值,在计算两个区间的父节点的值时,需要将两个区间合并,那么看左边区间的右端点和右间左端点是否相同,若相同则表明这两个区间可以合并,直接将两者相加.而当不相等时,说明此时需要进行取反操作,则在两区间贡献相加的情况下还要多加1.然后就是区间修改,因为是区间修改,所以想到懒人标记,只是这里是每次修改将左右端点的值和懒人标记的值^=1即可.

#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
struct node
{
    int l,r;
    int sum,lz;
    int lval,rval;
}tree[400005];
int arr[100005];
int n,m;
void push_down(int node)
{
    if(tree[node].lz)
    {
        tree[node<<1].lval^=1;
        tree[node<<1|1].lval^=1;
        tree[node<<1].rval^=1;
        tree[node<<1|1].rval^=1;
        tree[node<<1].lz^=1;
        tree[node<<1|1].lz^=1;
        tree[node].lz=0;
    }
    return ;
}
void push_up(int node)
{
    if(tree[node<<1].rval==tree[node<<1|1].lval)
        tree[node].sum=tree[node<<1].sum+tree[node<<1|1].sum;
    else
        tree[node].sum=tree[node<<1].sum+tree[node<<1|1].sum+1;
    tree[node].lval=tree[node<<1].lval;
    tree[node].rval=tree[node<<1|1].rval;
    return ;
}
void build_tree(int l,int r,int node)
{
    tree[node].l=l;
    tree[node].r=r;
    if(l==r)
    {
        tree[node].sum=0;
        tree[node].lval=arr[l];
        tree[node].rval=arr[l];
        tree[node].lz=0;
        return ;
    }
    int mid=(l+r)/2;
    build_tree(l,mid,node<<1);
    build_tree(mid+1,r,node<<1|1);
    push_up(node);
}
int query(int l,int r,int node)
{
    int res=0,flag=0;
    if(l<=tree[node].l&&tree[node].r<=r)
        return tree[node].sum;
    int mid=(tree[node].l+tree[node].r)/2;
    push_down(node);
    if(l<=mid)
        res+=query(l,r,node<<1),flag=1;
    if(r>mid)
    {
        if(flag==1)
        {
            if(tree[node<<1].rval==tree[node<<1|1].lval)
                res+=query(l,r,node<<1|1);
            else
                res+=(query(l,r,node<<1|1)+1);
        }
        else if(flag==0)
            res+=query(l,r,node<<1|1);
    }
    return res;
}
void update(int l,int r,int node)
{
    if(l<=tree[node].l&&tree[node].r<=r)
    {
        tree[node].lz^=1;
        tree[node].lval^=1;
        tree[node].rval^=1;
        return ;
    }
    int mid=(tree[node].l+tree[node].r)/2;
    push_down(node);
    if(l<=mid)
        update(l,r,node<<1);
    if(r>mid)
        update(l,r,node<<1|1);
    push_up(node);
}
int main()
{
    int op;
    scanf("%d%d",&n,&m);
    string s;
    cin>>s;
    for(int i=1;i<=n;i++)
        arr[i]=(s[i-1]-'0');
    build_tree(1,n,1);
    while(m--)
    {
        int l,r;
        scanf("%d%d%d",&op,&l,&r);
        if(op==1)
            printf("%d\n",query(l,r,1));
        else if(op==2)
            update(l,r,1);
    }    
    return 0;   
}

I.V字钩爪

登录—专业IT笔试面试备考平台_牛客网icon-default.png?t=M276https://ac.nowcoder.com/acm/contest/30896/I思维题,题意是不限操作次数,也就是尽量取完.我们可以把石头按照间隔来进行分组,将i,i+k,i+2*k......i+n*k(k为间隔大小,i为初始序号,i+n*k<=石头总数)分为一组.分组后,为了尽量让答案更大,只需要尽量取完即可.我们必须尽量让石头都是能够在距离一定的情况下成对.当某组里面的石头为偶数个时,就可以全部取完.为奇数个时,一定有一个取不了,为了让贡献最大,那么这一个肯定是在这一组的奇数位置上,去奇数位置上最小的减去,因为这样才能使剩下的石头在题目给定距离下成对.

#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#define int long long
using namespace std;
int arr[1000006];
signed main()
{
    int n,k,ans=0;
    scanf("%lld%lld",&n,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&arr[i]);
        ans+=arr[i];
    }
    for(int i=1;i<=k;i++)
    {
        int minn=1e9,tt=0;
        for(int j=0;i+j*k<=n;j++)
        {
            tt++;
            if(j%2==0)
                minn=min(minn,arr[i+j*k]);
        }
        if(tt%2==1)
            ans-=minn;
    }
    printf("%lld",ans);
    return 0;
}

继续努力

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-31 23:45:54  更:2022-03-31 23:46:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:11:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码