2020ccpc

先写一下我做出来的题目的思路和题解 1010  1007 1003
1010 Reprots
这道题很简单,看看样例就知道满足的条件:0和1间隔出现就行,用异或(^)来完成就可以,只要任意相邻两个数异或的结果是1,就是yes,反之就是no
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        int time;//声明次数
        cin>>time;
        int a[time];//建立数组
        int i;
        for(i = 0;i < time;i++ )//输入
        cin>>a[i];
        int flag = 1;//判断条件
        for(i = 0;i < time-1;i++)
        {
            if(a[i]^a[i+1])//判断两个相邻数是否不同
            {
                continue;
            }
            else {
                flag = 0;
                break;
            }
        }
        if(flag)
        {
            cout<<"YES"<<endl;

        }
        else cout<<"NO"<<endl;
    }
}
1007 CCPC Training Class
这个题的关键是读懂套娃的每一个部分都是什么意思(说实话,理解了一段时间):
Lborderi 是代表把数组的部分或者全部分成两部分之后相同的最大值,
D表示Lborderi的长度,
W表示所有满足条件的字符串数组的最大长度。
刚开始的时候没有思路,也一直在本子上模拟,究竟是啥意思,但是题目最后有一段话你可以任意地改变字符串s,让你可以随便排列字符串,
那我就把出现最多的字母放到开头就可以了,答案就变成了出现最多字母出现的次数
——————————————————————————————————————————
以上是补题过程中理解到的答案,实际情况是:
看了看样例,每一个样例的答案都是出现最多字母的的个数,然后试了试,,然后莫名其妙的ac了。
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;int cnt = 1;
    while(n--)
    {

        int a[26] = {0};//用长度为26的数组来表示26个字母,元素代表出现的次数
        string s;
        cin>>s;
        int len = s.length();
        for(int i = 0;i < len;i++)
        {
            a[s[i]-'a']++;
        }
        cout<<"Case #"<<cnt++<<": "<<*max_element(a,a+26)<<endl;
    }


}
1003 Express Mail Taking
题意是有n个保险柜,m个快递,k是其中一个保险柜,并且打开其他保险柜需要在k这个保险柜来操作,求最短路径的长度
最开始的时候读错题意了,就很纳闷,以为每拿一次快递就必须回到第k个保险柜那里,所以最后的结果是所有的有快递的保险柜距离k的距离乘以2开始和结束两次到k的距离就是最后的答案,这样的话哪还有最短路径啊,然后,,,,wa
但是题中并没有说最后一个快递拿完了还要回到k然后才能走,但实际上不必要,可以找一个比k小并且距离k最大的快递,最后出去的时候顺手拿了,这样就有最短路径了。
所以答案就是,从2*(k-1)+2*abs(i-k)-min(i)
代码是队友的,因为这个题不是我写的
#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\n",ans);
     } 
    return 0;
}
————————————————————————————————————
下面是补充的题目(时间关系只补充了两个题目)
1005 Lunch
一道博弈题,比赛期间没有做出来,本来以为比较简单的问题,但实际上有一定难度
题意:一堆数字,每一回合一个人可以将其中一个数字变成大小为原来的k分之一的k个数字,谁先把所有的数字都变成1谁就赢了,问先手能不能赢。
找了大佬分析了一下,然后得到了nim博弈这么一个新名词
nim博弈:有n堆石子,两人轮流进行操作,每次可从任意一堆石子里取走任意多枚石子,不能不取,问先手必胜还是必败。
结论:判单异或和是否为0,如果为0则必败,否则就改变其中最大的一堆,让分开后的结果异或和为0;
这道题可以理解为石子数目为质因数个数的nim博弈(要考虑平方数字,比如9 = 3*3,这里3 是2两个质因子)。
代码就不贴了。。。。。。。。。


1011 3x3 Convolution
给你一个n阶方阵和一个3阶方阵, 定义n阶矩阵C(A,K),他的每一个元素满足

又定义了Cm(A,K)=C(Cm−1(A,K),K) and C1(A,K)=C(A,K),求一下limt->∞Ct(A,K).
这个题问了问大佬,队友说这道题的数据不强,他取巧做的,如果数据加强,就gg了
输出样例只有两种,一个是原矩阵,一个是零矩阵
展开操作一下C1,1 = A1,1*K1,1+A1,2*K1,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,最终矩阵会变为0矩阵;
2.k1,1不为0
       这又要分两种情况:
            (1)除了K1,1,其他位置都是0;各个项都相当于变成了原来的t次方,整体比值不变,所以输出原矩阵
            (2)除了K1,1,其他位置有不等于0的,Cn,n会不断变小,最总去极限的话就是0;所以还是0矩阵。
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务