noip模拟赛#38

我打开了#39的problem。。。想了半个小时多发现我一道题都不会写。。。于是我打开了#38的problem

T1:循环数字的定义为能够将该数划分为若干相同长度的段并且都相同。 n=2e18.

=>我只会70%的暴力。。。

正解:

对于[L,R]内的循环整数个数,可以看成是[1,R]内的循环整数个数减去[1,L-1]内的循环整数个数。

对于确定了循环节长度i以及数字长度n的循环整数,在[1,x]内的个数可以用MAX{x div k-10^(i-1)+1,0}算出,其中k是i-1个0,1个1,循环n div i次所得的数字。

例如,若求[1,666666]内长度为6的循环节长度为3的数字只需要用666666 div 1001-100+1=567.如此即可快速算出数字个数。这个公式成立当且仅当x的数字长度等于n。也就是说[1,666666]内长度为5的循环节长度为1的数字等于99999 div 11111-1+1=9.不能使用666666作为被除数。

所以就可以枚举循环节长度以及数字长度,利用以上公式算出循环整数的数字个数。

但是,很容易发现,这种做法会引起重复计算。因为如果一个整数的循环节长度是i,那只要k*i是数字长度的约数,k*i也是该整数的循环节长度,所以每次计算循环节长度为i的循环整数个数的时候也要把循环节长度为i的约数的所有合法循环整数减去。

也就是说,9999在循环节长度是1的时候已经算了一遍,而在循环节长度为2的时候也会算一次,所以要减去。

时间复杂度为O(T*(lgMAX{R})^2),期望得分100%。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define clr(x,c) memset(x,c,sizeof(x))
int read(){
	int x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-‘0‘,c=getchar();
	return x;
}
const int nmax=2e6+5;
const int inf=0x7f7f7f7f;
int a[nmax],be[10];
bool pd(int x){
	int cnt=0;while(x) be[++cnt]=x%10,x/=10;
	if(cnt%2||cnt==2){
		rep(i,2,cnt) if(be[i]!=be[i-1]) return 0;
		return 1;
	}else{
		if(cnt==4){
			if(be[1]==be[3]&&be[2]==be[4]) return 1;
			return 0;
		}else{
			if(be[1]==be[3]&&be[1]==be[5]&&be[2]==be[4]&&be[2]==be[6]) return 1;
			if(be[1]==be[4]&&be[2]==be[5]&&be[3]==be[6]) return 1;
			return 0;
		}
	}
}
int main(){
	freopen("circulate.in","r",stdin);freopen("circulate.out","w",stdout);
	rep(i,11,nmax-1) a[i]=a[i-1]+pd(i);
	int n=read(),u,v;
	rep(i,1,n){
		u=read(),v=read();
		printf("%d\n",a[v]-a[u-1]);
	}
	fclose(stdin);fclose(stdout);
	return 0;
}

T2:求多少个长度为n的严格单调递增或严格单调递减的数列。数列的数字[1,n]。n=1e6+5;mod=2e6+3;

=>打表可以发现规律。ans=C(n-1,n-1-n+1)+C(n,n-n+1)+···+C(2*n-2,2*n-2-n+1)。ans=ans*2-n。看出这个之后线性求逆元就可以了。

正解:

我们可以想象,如果要数列不递增或不递减(不考虑只有一种数的情况)那么就可以选出若干个数再排序,所以是一个组合题,不是排列题。

然后我们可以在n-1个空里面放上i个挡板,没有放挡板的位置代表其相邻两个数相等。

如1 / 2,2,2 / 3,就是一个只放了2个挡板的序列,于是我们可以在n-1个数里面取i个位置放挡板,然后从N个数里面取出i个数放进去ANS=sigma{C(N-1,i-1)*C(N,i),1<=i<=N},由于两个组合数确定了一个参数,另一个参数几乎都需要用到,我们可以使用递推。

C(N,0)=1;  C(N,i)=C(N,i-1)*(n-i) div (i+1) 于是就可以递推出所有C(N,i),C(N-1,i)

由于有求余操作,我们可以使用逆元,实现div。

时间复杂度为O(NlogN),期望得分100%。

好神啊。。。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define clr(x,c) memset(x,c,sizeof(x))
#define ll long long
int read(){
	int x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-‘0‘,c=getchar();
	return x;
}
const int nmax=2e6+5;
const int inf=0x7f7f7f7f;
const int mod=2e6+3;
int inv[mod+1],fac[nmax];
int main(){
	freopen("array.in","r",stdin);freopen("array.out","w",stdout);
	inv[1]=1;
	rep(i,2,mod) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
	int n=read();
	fac[1]=1;rep(i,2,n+n) fac[i]=1ll*fac[i-1]*i%mod;
	int ans=1;
	rep(i,2,n) ans=(ans+1ll*fac[n+i-2]*inv[fac[i-1]]%mod*inv[fac[n-1]]%mod)%mod;
	printf("%d\n",(ans+ans-n+mod)%mod);
	fclose(stdin);fclose(stdout);
	return 0;
}

T3:给出一个长度为n的数列。数列中的数[1,n]。求最多能够组成多少个长度为3的严格上升序列。

=>想啊想想啊想。。。想他的性质的时候突然想到数的大小是没有用的。。。关键是统计每个数字有多少个后搞。然后贪心。先尽量去那些个数多的。那么弄三个指针扫一下就好了。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define clr(x,c) memset(x,c,sizeof(x))
int read(){
	int x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-‘0‘,c=getchar();
	return x;
}
const int nmax=3e6+5;
const int inf=0x7f7f7f7f;
int a[nmax];int vis[nmax];
int main(){
	freopen("cakes.in","r",stdin);freopen("cakes.out","w",stdout);
	int n=read(),u,cnt=0;
	rep(i,1,n){
		u=read();
		if(!vis[u]) vis[u]=++cnt;
		a[vis[u]]++;
	}
	sort(a+1,a+cnt+1);
	//rep(i,1,cnt) printf("%d ",a[i]);printf("\n");
	int ca=cnt-2,cb=cnt-1,cc=cnt,ans=0,tmp;
	while(ca>0&&cb>0&&cc>0&&ca<cb&&cb<cc){
		//printf("%d %d %d\n",ca,cb,cc);
		++ans;--a[ca];--a[cb];--a[cc];
		if(!a[cc]){
			tmp=cb,cb=ca,--ca,cc=tmp;
			if(!a[cc]) tmp=cb,cb=ca,--ca,cc=tmp;
			if(!a[cc]) tmp=cb,cb=ca,--ca,cc=tmp;
		}
		if(!a[cb]) {
			cb=ca,--ca;
			if(!a[cb]) cb=ca,--ca;
		}
		if(!a[ca]) --ca;
	}
	printf("%d\n",ans);
	fclose(stdin);fclose(stdout);
	return 0;
}
/*
6
1 2 3 4 3 2
6
1 1 1 2 2 3
12
1 1 2 5 8 2 2 2 3 3 3 1 3
*/
时间: 2024-08-22 13:52:18

noip模拟赛#38的相关文章

NOIP模拟赛 6.29

2017-6-29 NOIP模拟赛 Problem 1 机器人(robot.cpp/c/pas) [题目描述] 早苗入手了最新的Gundam模型.最新款自然有着与以往不同的功能,那就是它能够自动行走,厉害吧. 早苗的新模型可以按照输入的命令进行移动,命令包括‘E’.‘S’.‘W’.‘N’四种,分别对应东南西北.执行某个命令时,它会向对应方向移动一个单位.作为新型机器人,它可以执行命令串.对于输入的命令串,每一秒它会按命令行动一次.执行完命令串的最后一个命令后,会自动从头开始循环.在0时刻时机器人

【简单思考】noip模拟赛 NTR酋长

NTR酋长 (ntr.pas/.c/.cpp) 黄巨大终于如愿以偿的进入了czy的后宫中……但是czy很生气……他要在黄巨大走到他面前的必经之路上放上几个NTR酋长来阻挡黄巨大. 众所周知,NTR酋长有一个技能是沟壑(F).它会在地图上产生一条长长的障碍物阻挡人前进.Czy打算在一个n*m的矩形(必经之路?)中放上NTR酋长.NTR酋长要一个一个放下去,而且每放一个都会向四角倾斜的方向放出无限长的沟壑,而已经被沟壑挡住的地方就不能再放NTR酋长了. 请注意:不会出现沟壑的路径挡住另一个沟壑的情况

【noip模拟赛】 射击

这题似乎是什么安阳一中的模拟题,不管了,反正是学长出的noip模拟赛里面的题目.... 射击(shoot.pas/.c/.cpp) 时间限制:1s,内存限制128MB 题目描述: 据史书记载,对越反击战时期,有位中国侦察兵,他的代号叫814.一天他执行狙击任务,他的任务地区是n座恰巧在一条直线上的山.这些山所在直线恰巧为东西走向,山从东到西依次编号为1~n.一天814隐藏在编号为k的山上,每座山上都有1个目标. 814也非常的厉害,任务结束时杀了很多人,可是史书中只记载了两点: 1:814一定攻

NOIP模拟赛

#1[Nescafé 31]杯NOIP模拟赛 t1 题意:n*m的棋盘上从(1,1)走到(n,m),只能向下或向右,一些格子有老鼠,每个老鼠互不相同,当处于与老鼠有重边的格子时,视为看见了这只老鼠,求到终点看到最少的不同老鼠数. 分析:DP 由于求得是看到的不同的老鼠数目,不能直接用过河卒做,因为同一个位置的老鼠可能会统计多次,我们还需要增加一维即方向. f[i,j,0]表示到从上面一个格子走到(i,j)时最少老鼠数,f[i,j,1]表示左边. f[i,j,0]:=min(f[i-1,j,0]+

2012-10-20 NOIP模拟赛

      2012-10-20 NOIP模拟赛 by coolyangzc 共3道题目,时间3小时 题目名 高级打字机 不等数列 经营与开发 源文件 type.cpp/c/pas num.cpp/c/pas exploit.cpp/c/pas 输入文件 type.in num.in exploit.in 输出文件 type.out num.out exploit.out 时间限制 1000MS 1000MS 1000MS 内存限制 256MB 256MB 256MB 测试点 5+(5) 10

2017 9 11 noip模拟赛T2

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=205; int map[N][N]; int d[N],tag[N],book[N],f[N]; int n,m; void work(int x) { memset(d,63,sizeof(d)); memset(book,0,sizeof(book)); memset(f,0,sizeof(

【noip模拟赛4】Matrix67的派对 暴力dfs

[noip模拟赛4]Matrix67的派对 描述 Matrix67发现身高接近的人似乎更合得来.Matrix67举办的派对共有N(1<=N<=10)个人参加,Matrix67需要把他们安排在圆桌上.Matrix67的安排原则是,圆桌上任意两个相邻人的身高之差不能超过K.请告诉Matrix67他共有多少种安排方法. 输入 第一行输入两个用空格隔开的数N和K,其中1<=N<=10,1<=K<=1 000 000. 第二行到第N+1行每行输入一个人的身高值.所有人的身高都是不

2014-11-3 NOIP模拟赛2

NOIP 2014 水题模拟赛 (请选手务必仔细阅读本页内容) 一.题目概况 中文题目名称 数列 刷漆 排队 英文题目与子目录名 seq paint layout 可执行文件名 seq paint layout 输入文件名 seq.in paint.in layout.in 输出文件名 seq.out paint.out layout.out 每个测试点时限 2 秒 1 秒 1 秒 测试点数目 10 10 10 每个测试点分值 10 10 10 附加样例文件 无 无 无 结果比较方式 全文比较(

liu_runda 给辣鸡蒟蒻做的 NOIP模拟赛 1.0 第二题 任(duty) 题解

问题 B: 任(duty) 时间限制: 2 Sec  内存限制: 512 MB 题目描述 liu_runda退役之后就失去梦想开始咸鱼生活了- Bilibili夏日画板活动中,所有人都可以在一块画板上进行像素画创作.UOJ群有一群无聊的人决定在画板上创作一个50*50的UOJ的LOGO.如下图. 这块画板实际上是很大的矩形网格.一个网格是一像素. 一个人每三分钟才能画一个像素.所以liu_runda的咸鱼生活非常无聊. 郭神表示他实在是看不下去liu_rudna这只颓狗了,于是随手出了一道神题,