2020 CCPC - 网络选拔赛 签到计划

1010签到,判断序列相邻的数字是否不同

#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
const int maxn = 15;
long long a[maxn];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        int ans = 0;
        for(int i = 1; i <= n; i++)
        {
            cin >> a[i];
            if(a[i] == a[i-1] && i != 1)
            {
                ans = 1;
            }
        } 
        if(ans) cout << "NO" << endl;
        else cout << "YES" << endl;
    }
    return 0;
}

1007,签到结论题:给你一个字符串,求字符串对应表达式的最大值

OI佬直接猜到了结论:输出所有字母中出现次数最多的那个,出现次数即可。

#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
int a[30];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    for(int k = 1; k <= t; k++)
    {
        for(int i = 0; i <= 26; i++) a[i] = 0;
        string s;
        cin >> s;
        int ans = 0;
        for(int i = 0; i < s.length(); i++)
        {
            a[s[i]-'a']++;
        }
        for(int i = 0; i < 26; i++)
        {
            ans  = max(ans,a[i]);
        }
        cout << "Case #" << k << ": " << ans << endl;
    }
    return 0;
}

1003,签到贪心,超市的寄存柜,锁位于k,每次开锁之后拿完快递就要再回到锁再开锁,(即:每次开锁只能拿一个)。求最小距离

顺序无所谓,只要最后一个快递是距离门1最近的就可以了。
注意一开始从门到k也要算进总距离

#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
const int maxn = 1e6 + 50;
int a[maxn];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        long long n,m,k;
        scanf("%lld%lld%lld",&n,&m,&k);
        for(int i = 1; i <= m; i++)
        {
            scanf("%d",&a[i]);
        }
        sort(a+1,a+1+m);
        long long ans = 0;
        for(int i = 2; i <= m; i++)
        {
            ans += 2 * abs(k-a[i]);
        }
        ans += k-1;
        ans += abs(k-a[1]);
        ans += a[1] - 1;
        printf("%lld\n",ans);
    }
    return 0;
}

1011,签到结论题,给你两个矩阵,求表达式的极限值。

我们先要用已知的 k’ 矩阵去求 k 矩阵.
由k矩阵的表达式可以知道,k矩阵只可能有两种

  1. 矩阵全0
  2. 矩阵有且只有一位不是0,且值为1

很显然,对于全0的k矩阵,我们最终的答案也是全0的一个矩阵。
其次,对于只有一位是1的k矩阵:
只有左上角为1的时候为输出原矩阵,否则在取极限的过程当中,都会变成全0矩阵。

结论给的过于突兀了
举个例子:
3*3的k矩阵,只有左上角为1,那么新生成的c[x][y] = A[x-i+1][y-j+1]。
带入i = 1,j = 1,得到c[x][y] = A[x][y].

如果是k[1][2] = 1,其他位为0,我们也尝试一下。
新生成的C[x][y] = A[x-i+1][y-j+1] = A[x][y-1].
每次进行操作,都是将当前的A矩阵向右平移一列,左边的列用0补齐。
进行n次之后,就会得到一个全0的矩阵。

#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
const int maxn = 55;
int a[maxn][maxn];
int b[5][5];
int c[maxn][maxn];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= n; j++)
            {
                cin >> a[i][j];
            }
        }
        int sum = 0;
        for(int i = 1; i <= 3; i++)
        {
            for(int j = 1; j <= 3; j++)
            {
                cin >> 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++)
                {
                    if(j != n)
                    cout << 0 << " ";
                    else cout << 0 << endl;
                }
            }
        }
        else
        {
            for(int i = 1; i <= n; i++)
            {
                for(int j = 1; j <= n; j++)
                {
                    if(j != n)
                    cout << a[i][j] << " ";
                    else cout << a[i][j] << endl;
                }
            }
        }
    }
    return 0;
}

1005,博弈论,尼姆博弈,给你n根木棍,你可以将一根木棍分为等长的若干份(最短为1),谁不可以分解便输掉了游戏,问谁会输。

当初写的时候就是没想到怎样转化成尼姆博弈,现在想想真就差一步。真菜

可以将每根木棍想象成一对石子,那么尼姆博奕是从石头堆当中拿1~全拿。正好对应上将木棍分解一次到全部分解到1.
问题来了,尼姆博奕是拿走石头,你这个是分解木棍,怎么能一样呢?
我们每次分解木棍,就是从整个长度当中除去一个因数。我们可以将木棍长度的因数比作石头堆的石子。
即:对木棍的长度分解质因数,每个质因数出现一次,就是有一个相应的石子。
注意:质因数为2的时候是个特例,为啥?
因为你在分解2的时候,将长度分解成2个其他的数字,总次数+2,奇偶性质不变,不影响胜负。
只有你第一次分解2的时候,第一刀会影响总操作次数,之后多次分解2,都是偶数了。
所以,得到结论:对长度分解质因数(2的话只记录一次),求异或和套用尼姆博奕即可。
注意:用int,longlong超时…

欧拉线性筛素数,根号n(时间复杂度)分解质因数

#include <iostream>
#include <algorithm>
#include <map>
#include <cstring>
using namespace std;
const int maxn = 32000;
int a[15];
int prime[maxn] = {0};
//就是个素数表
int num=0;
bool sf[maxn];        //判断这个数是不是素数,sf[i]中的i是从1到maxn的数
void oulashai(){         //核心 欧拉筛代码
        //num 用来记筛到第几个质数
    memset(sf,true,sizeof(sf));
    for(int i=2;i<=maxn;i++)
	{          //外层枚举1~maxn
        if(sf[i]) prime[++num]=i;      //如果是质数就加入素数表
        for(int j=1;j<=num;j++)
		{       //内层枚举num以内的质数
            if(i*prime[j]>maxn) break; //筛完结束
            sf[i*prime[j]]=false;      //筛掉...
            if(i%prime[j]==0) break;   //避免重复筛
        }
    }
    sf[1]=false;
    sf[0]=false;  //1 0 特判 
}
int judge(int a)
{
	int ans = 0;
	if(a % 2 == 0)
	{
		ans++;
		while(a % 2 == 0)
		{
			a /= 2;
		}
	}
	for(int i = 1; i <= num; i++)
	{
		if(prime[i] * prime[i] > a) break;
		if(a % prime[i] == 0)
		{
			while(a % prime[i] == 0)
			{
				ans++;
				a /= prime[i];	
			}
		}	
	}
    if(a > 1) ans++;
    return ans;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    oulashai();
  //  cout << num << endl;
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        int ans = 0;
        for(int i = 1; i <= n; i++)
        {
            cin >> a[i];
            a[i] = judge(a[i]);
            ans ^= a[i];
        }
        if(ans == 0) cout << "L" << endl;
    	else cout << "W" << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值