SDUT 2021 Spring Individual Contest(for 20) - 1

A - Sherlock Bones

cf链接地址

The great dog detective Sherlock Bones is on the verge of a new discovery. But for this problem, he needs the help of his most trusted advisor -you- to help him fetch the answer to this case.
He is given a string of zeros and ones and length N.
Let F(x, y) equal to the number of ones in the string between indices x and y inclusively.
Your task is to help Sherlock Bones find the number of ways to choose indices (i, j, k) such that i < j < k, sj is equal to 1, and F(i, j) is equal to F(j, k).

input

The first line of input is T – the number of test cases.

The first line of each test case is an integer N (3 ≤ N ≤ 2 × 105).

The second line is a string of zeros and ones of length N.

output

For each test case, output a line containing a single integer- the number of ways to choose indices (i, j, k).

example:

3
5
01010
6
101001
7
1101011

2
3
7

Time limit —— 1500 ms
Memory limit —— 262144 kB

题意:
给你01串,你需要找出能够满足以下条件的区间( i , j , k)的个数
① i < j < k ,
② 下标 j 所代表的数字为1
③ 区间 [i , j] 中1的个数和区间 [j , k] 的1的个数相同
问:符合上述条件的(i , j , k)有几个?

刚开始做的时候真的一点没想到DP,看了好久只能看出暴力,2e5的数据暴力又必超时,后来看了好多题解,终于看出点头绪来,做法是真的妙。

分析:
从这些条件中我们可以看出一些性质: [i , k] 中1 的个数必定是奇数且至少是1
所以我们需要任意区间的1的个数
①用前缀和预处理字符串,用g[i]表示1~i之间1的个数
我们还需要知道该区间是奇是偶,开二维数组处理区间的奇偶在2e5的长度上显然不可取,所以我们需要一点折中操作,我们只处理 i~n 的奇偶区间数,然后最后处理时从后往前遍历,
②找出 i~n 的1的奇偶区间数
这里就要运用到DP了
dp[i][0]是 i~n 中1的个数为偶数的区间个数
dp[i][1]是 i~n 中1的个数为奇数的区间个数
ps:这里要好好想想,dp数组代表的是区间的个数
代码:

		if(a[i]=='1')//当a[i]==1时,当前的奇数区间=之前的偶数区间+1,
		{
   			 //				当前的偶数区间=之前的奇数区间
			dp[i][1]=dp[i+1][0]+1;
			dp[i][0]=dp[i+1][1];
		}
		else//当a[i]==0时,当前的奇数区间=之前的奇数区间
		{
   	//			   当前的偶数区间=之前的偶数区间+1
			dp[i][1]=dp[i+1][1];
			dp[i][0]=dp[i+1][0]+1; 
		}

③对 i 进行枚举,只要 [i,k] 中1的个数为奇数个,那么就一定存在符合条件的区间
关于这个k的问题,我们其实在求dp数组时就已经解决了,dp数组记录了后面所有的奇偶区间,我们要先找到一个离 i 最近的 j1 ,a[j1]=1且j1!=i
当a[i]=1时,[i,j1] 中1的个数是偶数,所以我们要找到若干个奇数区间 [j1+1,k],而dp数组记录的就是奇偶区间的个数,也就是说我们要找的奇数区间的个数就是dp[j1+1][1],这里面包含了k的所有情况,我们知道k的范围是 (j1+1,n],我们要找的就是k在这范围内所有情况中奇数区间的个数
同理,当a[i]=0时,[i,j1] 中1的个数是奇数,我们要找的偶区间 [j1+1,k]的个数就是dp[j1+1][0]
所以,枚举所有 i 的情况,累加他们,即可得到最终答案

代码:

#include<iostream>
#include<string.h>
using namespace std;
const int N=2e5+10;
int dp[N][2];
int g[N];
int main()
{
   
	int t;
	cin>>t;
	while(t--)
	{
   
		memset(g,0,sizeof(g));
		memset(dp,0,sizeof(dp));
		int n;
		string a; 
		cin>>n>>a;
		g[0]=a[0]-'0';
		for(int i=1;i<n;i++)//g数组记录1的前缀和 
		{
   
			g[i]=g[i-1]+a[i]-'0';
		}
		for(int i=n-1;i>=0;i--)
		{
   
			if(a[i]=='1')//当a[i]==1时,当前的奇数区间=之前的偶数区间+1,
			{
   			 //				当前的偶数区间=之前的奇数区间
				dp[i][1]=dp[i+1][0]+1;
				dp[i][0]=dp[i+1][1];
			}
			else//当a[i]==0时,当前的奇数区间=之前的奇数区间
			{
   	//			   当前的偶数区间=之前的偶数区间+1
				dp[i][1]=dp[i+1][1];
				dp[i][0]=dp[i+1][0]+1; 
			}
		}
		long long ans=0;
		int flag=0;
		int j1=n;
		for(int i=n-1;i>=0;i--)
		{
   
			if(flag==0)//先找到第一个离i最近的j1 
			{
   
				if(a[i]=='1')
				{
   
					flag=true;
					j1=i;	
				}
			}
			else//找到j1后判断[i,j1]区间中1个数的奇偶 
			{
   
				if((g[j1]-g[i]+a[i]-'0')%2==0)
				{
   
					ans+=dp[j1+1][1];//如果是偶数,那么就需要找到[j1+1,k]的奇数区间的个数 
				}
				else
				{
   
					ans+=dp[j1+1][0];//如果是奇数,那么就需要找到[j1+1,k]的偶数区间的个数
				}
				if(a[i]=='1')
				{
   
					j1=i;//因为j1的属性是距离i最近的1的下标,所有要一直更新 
				}
			}
		}
		cout<<ans<<endl;
	}
}

总结:这题做的时候的步骤应该是 推出 [i,k] 中1的个数为奇数——枚举i和k发现行不通——结合第一步发现 j1和[j1+1,k]的性质——想到dp——推动态转移方程。
反正我当时卡在第二步就放弃看别的题了。。。

B - Unusual Team

cf链接地址

A lion, a mouse, and a beaver are one of the best teams at Animal University, and they have qualified to the ACM Arabella 2017 contest!
They want to choose their team name, and after many suggestions, they have reduced their options to two names: “FunkyMonkeys” and “WeWillEatYou”.
They then created a poll on Facebook to help them with their final decision.
The results of the poll are now with Dr. Samer, and he will use the name with the highest votes to register the team. Can you help Dr. Samer to know which team name they will register with?

input

The first line of input is T – the number of test cases.
The first line of each test case contains two integers a, b (1 ≤ a, b ≤ 100) - the number of votes for “FunkyMonkeys” and “WeWillEatYou” respectively.

output

For each test case, output a single line containing “FunkyMonkeys” (without quotes), if that name received more points or tied with “WeWillEatYou”, otherwise output “WeWillEatYou”.

example:

2
15 20
70 70

WeWillEatYou
FunkyMonkeys

Time limit —— 1000 ms
Memory limit —— 262144 kB

题意:
真不敢相信cf上有这种题,意思是选队名,a是“FunkyMonkeys”这个队名的票数,b是“WeWillEatYou”队名的票数,输出多的那个

#include<iostream>
using namespace std;
int main()
{
   
	int a,b,t;
	cin>>t;
	while(t--)
	{
   
		cin>>a>>b;
		if(a>=b) cout<<"FunkyMonkeys\n";
		else cout<<"WeWillEatYou\n";
	}
}

C - Cheap Kangaroo

cf链接地址

There are N kangaroos going out to eat at an Indian restaurant. The ith kangaroo wants to eat exactly xi food. The kangaroos all want to order the same size of plates, but each one can order more than one plate for themselves if they need to. If the kangaroo orders more than he needs, he can simply hide the leftovers in his pouch.

At this Indian restaurant, the cost of the plate is the same as its size. Since Karl the Kangaroo is paying and is low on money, he wants to know what is the minimum cost to feed all N kangaroos and what is the largest possible size of the plates that satisfies this minimum cost?

input

The first line of input is T – the number of test cases.
The first line of each test case is an integer N (1 ≤ N ≤ 105).
The second line contains N space-separated integers xi (1 ≤ xi ≤ 109).

output

For each test case, output a line containing two space-separated integers – the minimum cost and the maximum plate size that corresponds to when the total cost is minimized.

example:

2
1
5
2
4 2

5 5
6 2

Time limit —— 1000 ms
Memory limit —— 262144 kB

题意:
有N个袋鼠,每个袋鼠想吃xi的食物,袋鼠们去饭店吃饭且都要一样大小的盘子,如果袋鼠要的食物比盘子大,那么可以多要几个盘子,每个盘子的成本和它的大小一样,你需要找到最小成本,以及在这个最小成本下盘子的最大尺寸
分析:
这道题题意有点模糊,它是让你优先找到最小的成本,然后再找到这个最小的成本中盘子的最大尺寸,最小成本很明确,就是 xi 的和 sum,设盘子尺寸为m,要保证每一个xi%m==0,这样才不会出现成本大于sum的情况
那么盘子尺寸m的身份就很明朗了,是所有 xi 的最大公约数
代码:

#include<iostream>
#include<algorithm>
using namespace std;
long long gcd(long long a,long long b)
{
   
	//这个gcd函数得自己写,__gcd函数不能处理longlong 
	if(b!=0) return gcd(b,a%b);
	return a;
}
int main()
{
   
	int t;
	//输入输出要么写快读,要么scanf printf ,不然会TLE 
	scanf("%d",&t);
	while(t--)
	{
   
		long long int n,m;
		long long sum=0;//注意要开longlong 
		scanf("%lld",&n);
		scanf("%lld",&m);//先令m=第一个数 
		sum=m;
		for(int i=1;i<n;i++)
		{
   
			long long int x;
			scanf("%d",&x);
			sum+=x;
			m=gcd(m,x);//更新m
		}
		printf("%lld %lld\n",sum,m);
	//	cout<<sum<<" "<<m<<endl;
	}
}
//顺带一提,我所有不用cin cout的代码都是因为vj上会卡输入用时

D - Magical Bamboos

cf链接地址

In a magical forest, there exists N bamboos that don’t quite get cut down the way you would expect.
Originally, the height of the ith bamboo is equal to hi. In one move, you can push down a bamboo and decrease its height by one, but this move magically causes all the other bamboos to increase in height by one.
If you can do as many moves as you like, is it possible to make all the bamboos have the same height?

input

The first line of input is T – the number of test cases.
The first line of each test case contains an integer N (1 ≤ N ≤ 105) - the number of bamboos.
The second line contains N space-separated integers hi (1 ≤ hi ≤ 105) - the original heights of the bamboos.

output

For each test case, output on a single line "yes” (without quotes), if you can make all the bamboos have the same height, and “no” otherwise.

example:

2
3
2 4 2
2
1 2

yes
no

Time limit —— 1000 ms
Memory limit —— 262144 kB

题意:
有N个竹子,它们有各有各的高度,你可以使其中任意一个竹子的高度-1,但同时其他竹子全部+1,这种操作可以进行任意多次,问能否使所有竹子高度一致
分析:
假设只有两根竹子,每次操作肯定使较高的-1,同时较矮+1,每次操作会使他们高差-2,所以我们只有当这两个竹子都奇或都偶时才能同高,换做n个竹子也一样,所以可以得出:是否能同高==是否都是奇数或偶数
代码:

#include<iostream>
using namespace std;
int main()
{
   
	int t;
	scanf("%d",&t);
	while(t--)
	{
   
		int n,m,flag,s=0;
		scanf("%d",&n);
		scanf("%d",&m);
		if(m%2==0) flag=0;
		else flag=1;
		for(int i=1;i<n;i++)
		{
   
			int x;
			scanf("%d",&x);
			if(x%2!=flag) s=1;
		}
		if(s==1) printf("no\n");
		else printf("yes\n");
	}
}

E - Competitive Seagulls

cf链接地址

There are two seagulls playing a very peculiar game. First they line up N unit squares in a line, all originally colored white.
Let L be the length of the longest continuous sub-segment of white unit squares. Let P be any prime that satisfies the condition that P<[ L 2 \frac{L

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值