10:26模拟赛

预计得分:(100+30+30)
实际得分:(100+0+20)
实实际得分:(100+30+20)




NOIP模拟赛

Reverse

题目描述

0比1小,所以1个串中如果0全在1前面,这个串就比较和谐。对于1个只包含
0和1的串,你每次可以将若干个0变成1,或者将若干个1变成0。那么,最少需要变多
少次才能把保证所有的0在1前⾯呢?

输入格式

一个01串。

输出格式

一个数即答案。

数据范围与约定

对于(40\%)的数据 ,(lenleq 20)
对于(70\%)的数据,(lenleq 1000)
对于(100\%)的数据,(lenleq 10^5)



做法:枚举0和1交界的位置
利用前缀和统计答案。
因为太水所以2分钟就做完了第一题

#include<iostream>
#include<cstdio>
#define N 500005
using namespace std;

void read(int & s){
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar());
	for(s=0;isdigit(ch);s=s*10+ch-'0',ch=getchar());
}

int n;
int s[N],q[N];

int main(){
	freopen("reverse.in","r",stdin);
	freopen("reverse.out","w",stdout);
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar());
	for(;isdigit(ch);s[++n]=ch-'0',ch=getchar());
	for(int i=1;i<=n;++i)
		q[i]=q[i-1]+s[i];
	int ans=0x3f3f3f3f;
	int qqq=0;
	for(int i=0;i<=n;++i){
		qqq=0;
		qqq+=q[i]+n-i-q[n]+q[i];
		ans=min(qqq,ans);
	}
	printf("%d",ans);
	return 0;
}





Number

题目描述

给定 ,求有多少数对(<x,y>)满足:
(x,yin [1,n],x<y)
(x,y)中出现的([0,9])的数码种类相同。

输入格式1个整数 。

输出格式输出1个数即答案。

数据范围与约定

对于(30\%)的数据,(nleq 10^3)
对于(100\%)的数据,(nleq 10^7)



做法:打表没打完而且代码只允许10KB而且只能过30%的数据
而且暴力都能打30分
所以这题打表失败了
本来想用组合数的相关内容做
但是不好维护而且代码应该会巨长巨恶心
就没写



正解思路:
首先统计出每个数其所有拥有数位的信息
因为产生<a,b>关系的数(A,B)其拥有的数码相同
这个可以通过下述方式达到
(S_n)表示(n)的数位信息

[S_n=sum_{i=0}^{9} 2^i(n/10^kequiv ipmod{10}) ]

则统计出所有数位相同的组数通过排列组合得出即可
我们设某一数位$S$的数量为$sum_S$,则易知$sum_S=C_{sum_S}^2$
因为每两个拥有数位S相同的数$a_1,a_2$
a_1
ot =a_2
所以对于任意$a_i,a_jin S$,都有$a_i
ot =a_j$
所以总共的$<a_i,a_j>$的个数为$C_{sum_S}^2$
所以最终答案为$sum_{i=1}^n C_{s_{S_i}}^2*s_{S_i}$
其中n为所以不同数位的个数





Wave

题目描述

给定一个长为(n)的数列,试求一个最长的不稳定波动子序列满足任意偶数项的
值不小于其相邻两项的值,且相邻两项的差不大于(k)

输入格式

输入第一行两个正整数 ;
第 n行 个非负整数描述这个数列。

输出格式

输出一个整数即答案。

数据范围及约定

对于(30\%)的数据,(nleq 10^3)
对于(70\%)的数据,(nleq 10^5)
对于(100\%)的数据,(nleq 2*10^6), 数列中的数不超过(2^{31}-1)



做法:(O(n^2)dp)
能过30的数据没问题
但是说好的(30\%)数据(10^3)
呢???怎么变(10^5)了……
这个做法可以用线段树优化
具体是用权值线段树维护
正解是贪心
考场上想到贪心
然后开始YY
有一段单增区间([l,r])
答案应该存在于([l,r])的两端才对
然后脑残的我竟然接着想如果([l,r])中存在一个很低的点
亲手把我自己的假设抛弃了
2333
然后就抛弃了正解做法
考后写了两份代码

#include<iostream>
#include<cstdio>
#define N 2000007
#define inf 0x7fffffff
using namespace std;

int s[N];
int que[N];

inline int read() {
	int x=0;
	char c=getchar();
	while(c<'0'||c>'9')c=getchar();
	while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();return x;
}

int main(){
	int n=read();
	int k=read();
    que[0]=inf;
    int now=0;
    for(int i=1;i<=n;++i)s[i]=read();
    for(int i=1;i<=n;++i){
        if(now&1){
    		if(s[i]>=que[now]+k)que[++now]=s[i];
    		if(s[i]<que[now])que[now]=s[i];
        }
        else {
    		if(s[i]+k<=que[now])que[++now]=s[i];
    		if(s[i]>que[now])que[now]=s[i];
		}
    }
    printf("%d",now);
    return 0;
}
#include<iostream>
#include<cstdio>
#define N 2000007
#define inf 0x7fffffff
using namespace std;

int n,k;
int s[N];
int que[N];

inline void read(int & s){
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar());
    for(s=0;isdigit(ch);s=s*10+ch-'0',ch=getchar());
}

int main(){
	read(n);read(k);
	int now=1;
	que[0]=inf;
	s[n+1]=inf;
	for(int i=1;i<=n;++i)read(s[i]);
	for(int i=1;i<=n;++i){
		if(now&1){
			while(s[i]+k>que[now-1]){
				if(s[i]>que[now-1])que[now-1]=s[i];
				i++;
			}
			while(s[i+1]<s[i]&&i<n)i++;
			if(que[now-1]<s[i]+k||i==n+1){
				break;
			}
			que[now]=s[i];++now;	
		}
		else {
			while(s[i]<que[now-1]+k){
				if(s[i]<que[now-1])que[now-1]=s[i];
				i++;
			}
			while(s[i+1]>s[i]&&i<n)i++;
			if(s[i]<que[now-1]+k||i==n+1){
				break;
			}
			que[now]=s[i];++now;
		}
	}
	int ans=0;
	printf("%d",now-1);
	return 0;
}
原文地址:https://www.cnblogs.com/qdscwyy/p/7737824.html