Namomo Test Round 2 AB题解 详细易懂

A
题目链接A题
题意分析
给你2n个数字,然后每次找两个数字相加,然后删除这两个数字,重复这两个操作,将每次相加的数字相乘然后对1e9+7取模输出,找到使这个答案最大的方案
题解
我是分析了题目给的样例后感觉出来的规律,方法稍稍有些不科学,但是结论是正确的,把这2n个数字排序,升序降序都可以,没区别,然后将头尾依次配对然后运算就可以了。我死在了没有开 long long 和把取模放在了结果输出而不是循环体里(我错了,错的离谱,说多了都是泪)
原理的证明可以看看这位兄弟的题解@solego
传送门大佬的题解
感谢他,我是看的他的题解才能弄懂这两题
开门!放代码

#include<bits/stdc++.h>
using namespace std;

const long long  maxn=1e9+7;

int main()
{
	long long n,m,res=1;
	scanf("%d",&n);
	m=2*n;
	long long a[m],b[n];
	for(int i=0;i<m;i++)
		cin>>a[i];
	sort(a,a+m);
	for(int i=0;i<n;i++)
	{
		b[i]=a[i]+a[m-i-1];
		res=(res*b[i])%maxn;	
	}
	cout<<res<<endl;
	return 0;
}

B
题目链接B题
题意分析
定义了一种字符串的形式,题目里都有就不多说了
我用一张图举了个例子,字有点丑(我在纸上写其实很好看的,在iPad上不知道咋回事儿,自己都看不下去)例子我感觉写的很清楚了,这个代码其实我是看的另外一个博主的题解,但是我看不太懂,然后我自己仔细想了想,所以这个题解应该算是很清楚的,希望能帮助到大家。如果有看不懂的地方我也可以在评论区再细说,有不对的地方也欢迎大家指正。
上图:
按照代码的运行顺序写的这个例子的运行顺序和解释
开门!上代码

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N = 5e5 + 10;
const int mod = 1e9 + 7; 
int n;
char s[N];
char str[] = "aeiou";

//偶数是否是元音 
bool check_even(char ch) {
	for(int i = 0; i < 5; i++)
		if(ch == str[i]) {
			return true;
		}
	return false;
}

//奇数是否不是元音 
bool check_odd(char ch) {
	for(int i = 0; i < 5; i++)
		if(ch == str[i]) {
			return false;
		}
	return true;
}

//同时满足三个条件才是namomo子串 
int check_pre(int fir) {
	int flag = 1;
	flag = (flag && check_odd(s[fir]) && check_odd(s[fir + 2]));//第一个和第三个不是元音 
	flag = (flag && check_even(s[fir + 1]) && check_even(s[fir + 3]));//第二个和第四个是元音 
	flag = (flag && s[fir + 2] == s[fir + 4] && s[fir + 3] == s[fir + 5]);//第二个=第四个 第三个=第五个 
	return flag;
}

int main()
{
	cin>>s+1;//数组首地址加一后的地址 
	int len = strlen(s + 1); //数组从1开始的长度 
	
	ll res = 0;
	if(len >= 6) 
	{
		for(int i = 1; i + 5 <= len; i++) 
		{
			if(check_pre(i)) //是namomo串 
			{
				res++;		//结果加一 
				int j = i + 6, k = i + 7;
				while(k <= len && s[j] == s[i + 4] && s[k] == s[i + 5])//没有超长同时后俩=前俩 
					 j += 2, k += 2;//再两个两个往后加 看是否依然符合 
				int slen = k - 2 - i + 1;//符合的最长的串长
				if(slen >= 8)//namomomomoqaqa例子中的 slen=10 
				{
					ll cnt = (slen - 6) / 2;//例子中临时变量cnt =2 表示后面多了两个相同的循环节 
					res += cnt; //以i开头的长度超过6的  
					res += cnt; //以i + 2, i + 4...开头的长度为6的  
					cnt--;//加完了就减掉防止重复 
					res += (cnt + 1) * cnt / 2;//以索引i+2,i+4...开头的长度大于6的
				}
				i = j - 2 - 1;//将上一个符合的最长的串的串尾作为下一次循环的串头,-1是因为循环条件里有个i++ 
 			} 
		}
	}
	cout<<res<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值