古代龙人的

【问题描述】
Mark Douglas是一名调查员。他接受了「调查古代龙人」的任务。经过千辛万苦,Mark终于找到了一位古代龙人。Mark找到他时,他正在摆弄一些秘药,其中一些药丸由于是从很久以前流传下来的,发出了独特的光泽。古代龙人告诉了Mark一些他想知道的事情,看了看手中的秘药,决定考一考这位来访者。古代龙人手中共有n粒秘药,我们可以用1表示「古老的秘药」,其余的用0表示。他将它们排成一列。古代龙人认为平衡是美的,于是他问Mark能选出多少个「平衡的区间」。「平衡的区间」是指首先选出一个区间[L, R],在它内部选出一个中间点mid,满足L<mid<R,mid是「古老的秘药」,且区间[L, mid]和[mid, R]中「古老的秘药」个数相等。
【输入格式】
输入文件名为puzzle.in。第一行为一个正整数idx表示该测试点所属的子任务编号,子任务的详细信息请见「数据范围」。样例的子任务编号为0。第二行为一个正整数n。第三行为一个长度为n的字符串,仅包含0和1。
【输出格式】
输出文件名为puzzle.out。输出仅一行表示答案。
【样例输入与输出】
0 7
1101011

7
【数据范围】本题采用捆绑测试,只有通过一个子任务中的全部测试点才能拿到这个子任务的分数。对于所有子任务:。、
各子任务分值及特殊约束如下:
子任务1(8%):n <= 50。
子任务2(26%):n <= 300。
子任务3(24%):n <= 2000。
子任务4(5%):字符串中仅有3个1。
子任务5(12%):字符串中全是1。
子任务6(25%)。

我在考场上耿直地一个一个子任务的写,然后比较智障地写了个n^3算法。后来我发现同一个意思用n * n就可以搞定(75分)…
正解有点可怕。。。我放弃理解了,就样吧。。。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
long long ans = 0;
int a[1000003],f[1000003];
int n,id;
int main()
{	scanf("%d%d",&id,&n);
	scanf("\n");
	for(int i = 1;i <= n;i++)	
	{		
		char c;		
		scanf("%c",&c);		
		a[i] = c - '0';			
		f[i] = f[i - 1] + a[i];	
	}	
	if(id == 4)//特判第四个点	
	{    	
		int s = 0;
	    	for(int i = 1;i <= n;i++)	
	    	{	  		
	    		if(a[i] == 1)b[++s] = i;
;	  		if(s == 3)break;
		}
	      	ans = (b[1] - 1)*(b[2] - b[1] - 1) + (n - b[3] + b[2] - b[1] - 1)*(b[3] - b[2] - 1) +1;      		int l = b[1] - 1,r = n - b[3]; 
	         if(l == 0)l = 1;
	         if(r == 0)r = 1;
	         ans += l * r; 
	         printf("%lld",ans); 
	         exit(0);
	}
	for(int i = 1;i <= n - 2;i++)	
	{	
		for(int j = i + 2;j <= n;j++)
			{
				if((f[j] - f[i - 1]) % 2 == 1)ans++;
				if((a[j] == 1 || a[i] == 1) && a[j] - a[i - 1] == 1)ans--;
			//如果一个区间,开头为1或结尾为1,且中间一切数均为0,则区间不合法 			}
	}	
	printf("%lld",ans);
	return 0;
}
   

希望gg不会因为我只写了一道题的题解就怼我。。。

猜你喜欢

转载自blog.csdn.net/qq_42914224/article/details/82824408