• 2018 JUST Programming Contest 1.0


    Time:2018.4.21  8:40-11:40

    Link

    Tutorial


    A

    题意

     

    分析

     


    B          solved by ym

    题意

    问平均数为a的n个数,最多有几个数不同

    分析

    ym:czh赛时清醒的发现可以尽量多的选,而不是直接是一个定值,总和n×a,尽可能多的选那么我们应该怎么选:显然我们想要更多不同的数字,那么我们一定是选择尽可能多的小的           数字,因为用一个大的数字代替几个小的数字会减少小的数的数量,故二分最多可以用多少个小的数,剩下的数用小的数“稀释”,check方法:n-mid>=(n×a-(mid+1)*mid/2)

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    const int maxn = 2e5+7;
    
    long long n,a;
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%lld%lld",&n,&a);
            ll l=1,r=n,mid;
            while(l<r)
            {
                mid=(l+r+1)>>1;
                if((n*a-mid*(mid+1)/2)>=n-mid)
                    l=mid;
                else
                    r=mid-1;
            }
            printf("%lld
    ",l);
        }
        return 0;
    }

    C             solved by  ym &czh

    题意

    问题可以转化为:给一个n,求小于n且与其互质的数(T<=1e5,n<=1e6)

    分析)

    ym:背锅,想到欧拉函数,但以为是质数= =,欧拉函数:对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目(φ(1)=1 ),显然一个欧拉函数就解决了


    D      solved by ym

    题意

    给一个无向图n个点m条边,每条边有一个权值w, 给出K个重要的点,问一个包含全部重要的点的子图的最小值 k (2 ≤ n ≤ 15) () (1 ≤ k ≤ n),

    分析

    ym:由于n很小,考虑状压dp,知道哪些点已经选,将没有选的点逐渐的添加到已选集合,dp[mask]:从mask状态下出发的最小值

    时间复杂度:由于每个点有2^n种状态,O(n*2^n)

    #include<bits/stdc++.h>
    #define sc scanf
    #define pr printf
    #define ll long long
    using namespace std;
    
    const int maxn = 15+7;
    
    int tot,head[maxn*maxn*2],to[maxn*maxn*2],nxt[maxn*maxn*2],w[maxn*maxn*2];
    int t,u,v,c,n,m,k;
    int Mask,ans,dp[(1<<16)+7];
    
    void init()
    {
        Mask=0;
        tot=0;
        memset(head,0,sizeof(head));
        memset(w,0,sizeof(nxt));
        memset(nxt,0,sizeof(nxt));
    }
    
    void add(int u,int v,int c){
        to[++tot]=v;
        w[tot]=c;
        nxt[tot]=head[u];
        head[u]=tot;
    }
    
    int maskdp(int x)
    {
        if(dp[x]!=-1)  return dp[x];
        if((x&Mask)==Mask) return 0;
        dp[x]=1e9;
        for(int i=0;i<n;i++)
        {
            if(((x>>i)&1))
            {
                for(int j=head[i];j;j=nxt[j])
                {
                    int v=to[j];
                    if(!((x>>v)&1))
                    dp[x]=min(dp[x],w[j]+maskdp(x|(1<<v)));
                }
            }
        }
        return dp[x];
    }
    
    int main()
    {
        sc("%d", &t);
        while(t--){
            init();
            sc("%d%d%d",&n,&m,&k);
            for(int i=1;i<=m;i++){
                sc("%d%d%d", &u,&v,&c);
                u--,v--;
                add(u,v,c),add(v,u,c);
            }
            int x;
            for(int i=1;i<=k;i++){
                sc("%d",&x);
                x--;
                Mask|=(1<<x);
            }
            int answer=1e9;
            memset(dp,-1,sizeof(dp));
            for(int i=0;i<n;i++)
            {
                answer=min(answer,maskdp(1<<i));
            }
            pr("%d
    ",answer);
        }
        return 0;
    }

    E       solved by ym

    签到


    F           solved  by ym

    题意

    给出一个n×m的网格,每个格子有一数字num,现有q条询问,每个询问给出询问的网格范围(a<=x<c ,b<=y<=d),问这些网格的median值(median:(2,1,3)==2,(4,2,3,1)==2)

    (T<=100,1<=n,m<=100,1<=q<=1e5,1<=num<=500,sum of  n×m <= 3×1e5,sum of  q<=1e6)

    分析

    由于num<=500,考虑用二维前缀和记录每个数字出现的频率,对于每次询问,median即为从小到大出现在出现median位置即可

    时间复杂度O(T*n*m*num)

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    int sum[105][105][505];
    int a[105][105];
    int now[505];
    int t,n,m,q;
    
    int main()
    {
        scanf("%d",&t);
        while(t--){
                memset(sum,0,sizeof(sum));
            scanf("%d%d%d", &n,&m,&q);
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    scanf("%d",&a[i][j]);
                }
            }
         //   cout<<123<<endl;
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    int na=a[i][j];
                    sum[i][j][na]++;
                    for(int k=1;k<=500;k++)
                    {
                        if(i==1){
                            if(j!=1){
                                sum[i][j][k]+=sum[i][j-1][k];
                            }
                        }
                        else {
                            if(j==1){
                                sum[i][j][k]+=sum[i-1][j][k];
                            }
                            else{
                                sum[i][j][k]=sum[i][j][k]+sum[i][j-1][k]+sum[i-1][j][k]-sum[i-1][j-1][k];
                            }
                        }
                    }
                }
            }
            //cout<<113<<endl;
            int x,y,xx,yy;
            while(q--)
            {
                memset(now,0,sizeof(now));
                scanf("%d%d%d%d",&x,&y,&xx,&yy);
                int allsum=(xx-x+1)*(yy-y+1);
                allsum=(allsum+1)/2;
                for(int i=1;i<=500;i++)
                {
                    int ans=sum[xx][yy][i]-sum[xx][y-1][i]-sum[x-1][yy][i]+sum[x-1][y-1][i];
                    allsum-=ans;
                    if(allsum<=0)
                    {
                        printf("%d
    ",i);
                        break;
                    }
                }
            }
        }
        return 0;
    }

    G

    题意

    几何

    分析

     czh来解决一下?


    H    solve by czh&ym

    题意

    给出一个字符串  下面给出n次替换,问有多少次替换执行完后,这个字符串成为一个回文串

    分析

    czh:首先统计有多少个左右不同的字符对,每次更改后,检查更改点字符对的变换,每次执行后如果不同的字符对为0则ans++。我的最大问题在于中点无论怎么变,num都不会改变。需要特判。


    I      

    签到 


    J     solved by  ym

    题意

    给一个区间[L,R],现给出一种切割,一个数可以从中间分成两半(1001???),这个数不含0并且前一半和后一半互质,问区间满足这种切割的最大值 

    分析

    ym:质数间隙了解一下?(暂且可以认为为320),暴力check


    K      solved by  ym

    题意

    给出ACM比赛的规则,问最后各个奖的归属

    分析

    ym:所以说写模拟题会送命

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=37;
    const int maxm=10000+7;
    
    struct node
    {
        int p,d,r,o;
        friend bool operator < (node a,node b){
            return a.o<b.o;
        }
    }t[maxm];
    
    int tt,n,m,k;
    bool v[maxn][maxn];///是否访问过
    int f[maxn][maxn]; /// 每个人每个题在答对之间错的次数
    int num[maxn]; ///每个队的一血数量
    int fb[maxn];
    int ans[maxn];
    string s;
    
    int hs()
    {
        int sum=0;
        sum=s[0]*100+s[1]*10+s[2]*1;
        sum*=60;
        sum+=s[4]*10+s[5];
        return sum;
    }
    
    int main()
    {
        scanf("%d",&tt);
        while(tt--)
        {
            scanf("%d%d%d", &n, &m,&k);
            memset(f,0,sizeof(f));
            memset(v,false,sizeof(v));
            memset(num,0,sizeof(num));
            for(int i=1;i<=k;i++)
            {
                scanf("%d%d%d",&t[i].p,&t[i].d, &t[i].r);
                cin>>s;
                t[i].o=hs();
            }
            for(int i=1;i<=n;i++) fb[i]=-1;
            for(int i=1;i<=m;i++) ans[i]=-1;
            sort(t+1,t+k+1);
            int st=-1,ed=-1,maxdd=0,maxf=0;
            for(int i=1;i<=k;i++)
            {
                int pp=t[i].p, dd=t[i].d, rr=t[i].r;
                if(rr==1){
                    ed=dd;
                    if(st==-1)  st=dd;
                    if(fb[pp]==-1) fb[pp]=dd;
                    if(!v[dd][pp])
                    {
                        num[dd]++;
                        maxdd=max(maxdd,num[dd]);
                    }
                    ans[dd]=max(ans[dd],f[dd][pp]);
                }
                else
                    f[dd][pp]++;
                v[dd][pp]=1;
            }
            for(int i=1;i<=n;i++)
                printf("%d%c",fb[i],i==n?'
    ':' ');
            printf("%d %d ",st,ed);
            for(int i=1;i<=m;i++)
                if(num[i]==maxdd)
                {
                    printf("%d ",i);break;
                }
            bool flag=true;
            maxf=-5;
            for(int j=1;j<=m;j++)
            {
                maxf=max(maxf,ans[j]);
            }
            for(int j=1;j<=m;j++)
            {
               if(ans[j]==maxf)
               {
                   cout<<j<<endl;
                   break;
               }
            }
        }
        return 0;
    }

    Summary

    Ym:菜菜啊,K题过的人好多,大家都会大模拟呀,这个水平去reginoal药丸,大力切题呀

    Czh:

  • 相关阅读:
    Vue源码解析-源码目录及源码调试运行
    Vue.js源码解析-从scripts脚本看vue构建
    ps 命令显示不完整的问题
    Linux中10个实用命令,千万不要错过
    Linux 下如何使用 fc 和 alias 命令
    Mac 查看正在后台运行(显示)的程序
    Mac 显示桌面
    Mac如何批量关闭同一个程序
    Mac 选中删除
    Mac 中 vscode 打开项目文件夹
  • 原文地址:https://www.cnblogs.com/Deadline/p/8900343.html
Copyright © 2020-2023  润新知