AcWing第28场周赛

1.子序列

题目不难,不过我一开始看错了,人家让求QAQ的序列数;

直接暴力就行了;

#include
using namespace std;

const int N = 1000010;

typedef long long LL;

int n;
string str;

int main()
{
	cin>>str;
	int res = 0;
	n = str.size(); 
	for(int i =0;i

2.最大公约数

这个题也不难,我们分析一下;

数组有两种情况:

1.整个数组都是质数;

2.整个数组不都是质数;

相对应的结果也有两种情况:

1.结果为1;

2.结果大于1;

我们需要求最大的结果,我们知道结果不可能大过数组中的最大值;

当结果大于1的时候,那数组中一定存在合数,且质因数的数量大于1(包含数组中本来就存在的质数);

我们只需要求得数组中合数的质因数,然后开一个数组存一下,各质因数出现的次数就行了;

最大的质因数就是我们要输出的答案了;

#include
using namespace std;

const int  N = 100010;

typedef long long LL;

int n;
int a[N],b[N];

bool isprime(int n)
{
	if(n == 1) return false;
	for(int i = 2 ; i <= n/i ; i++)
	{
		if(n%i == 0)return false;
	}
	return true;
}

int gcd(int a,int b) //没用
{
    return b ? gcd(b,a%b) : a;
}

int main()
{
	cin>>n;
	bool st = true;
	int maxx = 0;
	for(int i =0;i>a[i];
		maxx = max(maxx,a[i]);
	}
	
	for(int i =0;i

3.号码牌

这个题,想了一会,最后想出来了,是并查集,不过时间来不及了,害,还是基本功差点。

根据互换原则我们可以将小朋友分成不同的集合,每个集合中的小朋友的卡片的都可以互换到的(表达的不太清楚,不过应该可以看懂吧 [狗头] );

因为d[ i ] 是固定的,也就是说,每个小朋友互换的对象只有两个,要么 i - d[ i ] or i + d[ i ],当然要保证两个数据合法,然后将查到的数据的父结点指向当前数据的父节点就行了。

最后,我们只要判断一下,a[ i ] 的父节点和当前 i 的父节点是否是同一个就行了,也就是看看他们是否在一个集合中,如果在,就可以换到,如果不在就不行,感觉我这么说可能不太好理解,看代码感受一下吧。

#include
using namespace std;

const int N = 110;
typedef long long LL;

int n;

int a[N],d[N];
int p[N];

int find(int x)
{
	if(x != p[x]) p[x] = find(p[x]);
	return p[x];
}

int main()
{
	cin>>n;
    for(int i = 1; i <= n; i ++) cin>>a[i];
    for(int i = 1; i <= n; i ++) cin>>d[i];
    for(int i = 1; i <= n; i ++) p[i] = i;
    
    for(int i = 1; i <= n; i ++ )
	{
        int x = i - d[i], y = i + d[i];
        
        if(x >= 1)    p[find(x)] = find(i);
        
        if(y <= n)    p[find(y)] = find(i);
    }

    bool ok = true;

    for(int i = 1; i <= n; i ++ )
	{
        if(find(i) != find(a[i])) ok = false;
    }
    
    puts(ok ? "YES" : "NO"); //借鉴了某大佬的写法       
    
	return 0;	
}

可惜今天比赛不能加分了,感觉这周很水逆,上次cf掉了110分,我很伤心,这次不能加分,我更伤心,今天还把写好的结课论文搞没了,我还是重写一份,我好伤心啊,呜呜呜

你可能感兴趣的:(蓝桥杯,c++,算法)