• 2020CCPC网络赛


    在比赛开始30分钟内依次A了10,7,3,一个小时左右A了11,然后就再也没有写出任何一道题。。。

    其实比赛过程中心态有很大的问题,我一直在5上面钻牛角尖,耗费了太多时间。

    基本上比赛后半程三个人都在看2,5两道题,其他题目几乎没看。

    到最后基本没有做下去的欲望了,可能是因为是女队压力比较小吧(不,是因为我比较菜)。。

    以及网络赛的排行榜真的很迷。。第2题min25筛一堆人过。。然而队里三个人甚至都没有听说过这玩意。。

    (226大佬7题,ORZ)

    1002 Graph Theory Class

    题意:在一个有n个点的图中,图中点1~n编号。对于i,j之间的一条边,它的权重为lcm(i+1,j+1),求这个图的最小生成树大小。

    思路:很明显对于(j+1)为质数的情况,j应该与1连接,权重为2*(j+1);

    对于(j+1)不是质数的情况,j可以与任意一个满足i+1==factor(j+1)的i连接,factor(j+1)指j+1的因子,权重为j+1。

    于是最小生成树的大小为(3~n+1以内所有质数)*2+(3~n+1以内所有非合数),即(3~n+1所有数之和)+(3~n+1以内所有质数之和)

    前者可以用等差数列求和计算,(n+4)*(n-1)/2;由于n<=1010,后者可以使用min25筛计算。

    min25筛,可以在O(n3/4/logn)的时间内求积性函数f(x)的前缀和。

    (积性函数,指对于所有互质的整数a和b有性质f(ab)=f(a)f(b)的函数)

    (代码待补充

    1003 Express Mail Taking

    题意:有n个保险柜,编号为1~n,每两个相邻编号的保险柜之间的距离为1,第k个保险柜用来打开其他保险柜(每次只能同时打开一个保险柜)。从1出发,需要从m个保险柜中取东西后再从1离开。问距离最短的路线长度。

    思路:一开始理解错了题意,以为只要到达第k保险柜后其他保险柜就打开了,就WA了一次。

    对于m个要取东西的柜子,除了最后一个柜子有可能不需要返回k柜,对于其他柜子,都必须在该柜子与k柜之间走一个来回。

    于是找到m个柜子中最小的一个x,若x比k小,则将该点删去(在回1点的路上就可到达,对距离无贡献)

    接着对剩下的每个柜子i,贡献2*abs(i-k)的答案。

    再加上出发和结束的2*(k-1),就是答案。

    #include<cstdio>
    #include<cstring>
    #include<algorithm> 
    using namespace std;
    typedef long long ll;
    const int maxn=2000005;
    int a[maxn];
    int main()
    {
        int i,T,n,m,k,mi;
        ll ans;
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d%d%d",&n,&m,&k);
            ans=2ll*(k-1);
            mi=k;
            for (i=1;i<=m;i++) 
            {
                scanf("%d",&a[i]);
                ans+=2ll*abs(a[i]-k);
                if (a[i]<mi) mi=a[i];
            }
            if (mi!=k) ans-=2ll*abs(mi-k);
            printf("%lld
    ",ans);
         } 
        return 0;
    } 
    View Code

    1005 Lunch

    题意:有n个数,两人轮流进行操作,每次操作能将其中一个数x变为k*(x/k),此处的k必须是x的因子且k!=x。当场上的数均为1时游戏结束,当前操作方输。问先手可不可以获胜。

    思路:(看了半天别人的题解还是有点晕乎乎的)

    观察发现,对于一个数,分成偶数个会增加偶数个操作,于是这样不会使得最后的胜负情况发生改变。

    分成奇数个则刚好相反,会改变最后的胜负情况。

    把数x分解,x就变成了一堆质因子的乘积。

    ()

    因为每次操作要让这个数x变成自己的因数,所以每次必须取走x的至少一个质因子,

    那么就可以将这个数的所有质因子(考虑重复,因为假如你有2个质因子3,那么是可以分开取,所以重复的而要考虑)当作一堆石子的个数。

    而其中的2它比较特殊,因为它是偶数,不会使最后的胜负情况发生改变。

    于是不管分几次取2,都相当于直接把2全取走。但是又必须要取走2,所以就把所有的因数2当作一个石子一起取走。

    (以上来自队友的分析)

    然后就变成了nim博弈,即有n堆石子,两人轮流进行操作,每次可从任意一堆石子里取走任意多枚石子,不能不取,问先手必胜还是必败。

    对于答案,求每一堆的石子数的异或和,若为0则必败,否则必胜。

    (然后不知道为什么T了很久,好像也不是读入优化的问题啊。。。

    补充:对于nim答案的分析:对于一堆石子,只要石子数不为0,直接拿走所有石子就赢了,所以必胜。

    对于两堆石子,如果异或和为0则必败。此时两堆石子数相同,对方只要按照先手方对一堆石子的操作,对另一堆石子上进行同样的操作,就能够胜利。

    如果异或和不为0则必胜。先手方可以先将一堆石子变为和另一堆石子一样,然后就变成了刚才所说的局面,异或和为0。

    ......

    对于很多堆石子,如果异或和为0必败;否则改变其中最大的那堆的大小,一定能使剩下的局面的异或和为0。

    (局面异或和为0的具体操作:对手对一堆进行操作,其他堆中一定有某一堆,可以使先手对它做出相同的操作。

    #include<cstdio>
    #include<cstring>
    #include<algorithm> 
    using namespace std;
    int cnt,vis[32005],prime[5005];
    int div(int x)
    {
        int re=0;
        while (!(x&1))
        {
            x>>=1;
            re=1;
        }
        for (int i=2;i<=cnt && 1ll*prime[i]*prime[i]<=x;i++)
        {
            while (x%prime[i]==0)
            {
                x=x/prime[i]; 
                re++;
            }
        } 
        if (x!=1) re++;
        return re;
    }
    void pri(int n)
    {
        cnt=0;
        memset(vis,0,sizeof(vis));
        for (int i=2;i<n;i++)
        {
            if (!vis[i]) prime[++cnt]=i;
            for (int j=1;j<=cnt && 1ll*i*prime[j]<n;j++)
            {
                vis[i*prime[j]]=1;
                if (i%prime[j]==0) break;
            }
        }
    }
    int main()
    {
        int T,n,ans,x;
        pri(32000);
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d",&n);
            ans=0;
            for (int i=0;i<n;i++) 
            {
                scanf("%d",&x);
                ans^=div(x);
            }
            if (ans) printf("W
    ");
            else printf("L
    ");
        } 
        return 0;
    } 
    View Code

    1006 Robotic Class

    题意:给一个有n点的图,点i有k[i]条出边,若通过i的一条出边j,就会使当前的权值x变为c[i][j]*x+b[i][j],并走到下一点d[i][j]。对于有多条出边的点i,每次会选择一条满足a[i][j]x并且编号j最小的路径j。现在从任一点s出发,初始权值为x0,走到n点停止,最后到达n点的权值为Cs(x0),问对于每一个s,Cs(x)是否均为连续。

    思路:看完了别人的代码,感觉这题没做出来有点亏。。

    因为f(x)连续,所以若在i点的权值为a[i][j]-与a[i][j]+那么两者到达n点得到的权值应当相同。

    所以对于每一个点i的a[i][j],模拟以初始权值x0=a[i][j]-与a[i][j]+从i出发直到n的路径,检查最后得到的Ci(a[i][j]-)与Ci(a[i][j]+)是否相等。

    具体见代码。

    #include<cstdio>
    #include<cstring>
    #include<algorithm> 
    using namespace std;
    typedef long long ll;
    const int maxn=505;
    const int maxm=2005;
    int n,k[maxn],a[maxn][maxm],b[maxn][maxm],c[maxn][maxm],d[maxn][maxm];
    ll dfs(int t,ll x,int mark) 
    {
        if (t==n) return x;
        int pos=lower_bound(a[t],a[t]+k[t],x)-a[t];
        if (pos<k[t] && x==a[t][pos] && mark>0) pos++;
        int now=0;
        if (c[t][pos]>0) now=1;
        else if (c[t][pos]<0) now=-1;
        return dfs(d[t][pos],1ll*c[t][pos]*x+b[t][pos],now*mark);
    }
    int main()
    {
        int t,T,i,j,flag;
        ll l,r;
        scanf("%d",&T);
        for (t=1;t<=T;t++)
        {
            scanf("%d",&n);
            for (i=1;i<n;i++)
            {
                scanf("%d",&k[i]);
                for (j=0;j<k[i];j++) scanf("%d%d%d%d",&c[i][j],&b[i][j],&d[i][j],&a[i][j]);
                scanf("%d%d%d",&c[i][j],&b[i][j],&d[i][j]);
            }
            flag=1;
            for (i=1;i<n;i++) 
            {
                for (j=0;j<k[i];j++) 
                {
                    l=dfs(i,a[i][j],-1);
                    r=dfs(i,a[i][j],1);
                    if (l!=r) 
                    {
                        flag=0;
                        break;
                    }
                }
                if (!flag) break;
            }
            printf("Case #%d: ",t);
            if (flag) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    } 
    View Code

    1007 CCPC Training Class

    题意:花里胡哨的题面。

    思路:是一题题面比较长的签到题。。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int t,a[30],mx,pos,cs,l;
    char s[100010];
    
    int main()
    {
        scanf("%d",&t);
        while (t--)
        {
            scanf("%s",s+1);
            l=strlen(s+1);
            mx=0;
            memset(a,0,sizeof(a));
            for (int i=1;i<=l;i++)
                a[s[i]-'a']++;
            for (int i=0;i<26;i++)
                mx=max(mx,a[i]);
            printf("Case #%d: %d
    ",++cs,mx);
        }
        return 0;
    }
    比赛时代码

    1010 Reports

    题意:就是每次输入一个长度为n的01串,若存在相邻两位一样就输出NO,否则输出YES。

    思路:这么短的题目显然是签到题啦,照题意做就行了。

    #include<cstdio>
    using namespace std;
    int t,y,x,op,n;
    
    int main()
    {
        scanf("%d",&t);
        while (t--)
        {
            scanf("%d",&n);
            scanf("%d",&y);
            op=1;
            for (int i=1;i<n;i++)
            {
                scanf("%d",&x);
                if (x==y) op=0;
                y=x;
            }
            if (!op) puts("NO");
            else puts("YES");
        }
        return 0;
    }
    折服于队友的手速

    1011 3x3 Convolution

    题意:给出n*n矩阵A和3*3矩阵K(n>=3), 定义n*n矩阵C(A,K),它的每一项Cx,y满足

     定义Cm(A,K)=C(Cm1(A,K),K) and C1(A,K)=C(A,K)求limtCt(A,K)。

    思路:观察样例,发现样例中答案只有两种,原矩阵和零矩阵。

    经过一番胡乱分析,推测当输入的K矩阵只有左上角有不为0的数,其他位置都是0时,输出原矩阵;其他情况输出零矩阵,

    然后跟队友说了猜想,队友就A了,A得我一头雾水,果然像学长说的一样,大胆猜想,不用证明(bushi)。

    以及这题的输出格式真的。。。我写的时候PE了一片,(然而我的队友一发就过了。。

    补充:C1,1=A1,1*K1,1+A1,2*K1,2+......+A3,2*K3,2+A3,3*K3,3

    ......

    Cn,n-1=An,n-1*K1,1+An,n*K1,2

    Cn,n=An,n*K1,1

    然后进行分类讨论

    1、如果K1,1==0,Cn,n就为0;接下来的C2中的Cn,n-1也会变成0,以此类推,最后矩阵Ct会变成零矩阵。

    2、如果K1,1!=0,K其他位都为0,那么矩阵中的所有项相当于乘上了K1,1的t次方,各项之间的比值不变,于是答案是原矩阵。

    3、如果K1,1!=0,K其他位中存在不为0的项,因为K1,1<1Cn,n会不断变小,直至无限趋近于0

    推理可得,Ct中的Cn,n-1=An,n-1*Kt1,1+t*An,n*Kt-11,1*K1,2

    由于K所有项之和为1,K1,1与K1,2都小于1,分析可得当t∞时,Ct中的该项趋近于0;

    同理,其他项在Ct中也都趋近于0,于是最后得到的Ct是零矩阵。

    #include<cstdio>
    #include<cstring>
    #include<algorithm> 
    using namespace std;
    typedef long long ll;
    const int maxn=52;
    int a[maxn][maxn];
    int main()
    {
        int i,j,T,n,flag,x;
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d",&n);
            for (i=1;i<=n;i++)
            for (j=1;j<=n;j++) scanf("%d",&a[i][j]);
            flag=0;
            for (i=1;i<=3;i++)
            for (j=1;j<=3;j++) 
            {
                scanf("%d",&x);
                if (x)
                {
                    if (i==1 && j==1) flag=1;
                    else flag=0;
                }
            }    
            if (flag) 
            {
                for (i=1;i<=n;i++)
                for (j=1;j<=n;j++) 
                {
                    printf("%d",a[i][j]);
                    if (j==n) printf("
    ");
                    else printf(" ");
                }
            }    
            else 
            {
                for (i=1;i<=n;i++)
                for (j=1;j<=n;j++) 
                {
                    printf("0");
                    if (j==n) printf("
    ");
                    else printf(" ");
                }
            }
        }
        return 0;
    }
    这是我写的
    #include<cstdio>
    #define N 55
    using namespace std;
    int t,n,a[N][N],b[N][N],sum;
    
    int main()
    {
        scanf("%d",&t);
        while (t--)
        {
            scanf("%d",&n);
            for (int i=1;i<=n;i++)
                for (int j=1;j<=n;j++)
                    scanf("%d",&a[i][j]);
            sum=0;
            for (int i=1;i<=3;i++)
                for (int j=1;j<=3;j++)
                    scanf("%d",&b[i][j]),sum+=b[i][j];
            if (b[1][1]==sum)
                for (int i=1;i<=n;i++)    
                    for (int j=1;j<=n;j++)    
                        printf("%d%c",a[i][j]," 
    "[j==n]);
            else
                for (int i=1;i<=n;i++)
                    for (int j=1;j<=n;j++)
                        printf("0%c"," 
    "[j==n]);
        }
        return 0;
    }
    这是比赛的时候队友交的
  • 相关阅读:
    第2层交换和生成树协议(STP)__散知识点
    OSPF
    EIGRP和OSPF__EIGRP
    EIGRP和OSPF__邻居发现
    IP路由__距离矢量路由选择协议
    IP路由__动态路由
    IP路由__静态路由
    IP路由__IP路由选择过程
    Cisco的互联网络操作系统IOS和安全设备管理器SDM__CDP
    Cisco的互联网络操作系统IOS和安全设备管理器SDM__备份和恢复Cisco 配置
  • 原文地址:https://www.cnblogs.com/lsykk/p/13702367.html
Copyright © 2020-2023  润新知