NOIP2016 DAY2

T1:

可以预处理啊

开始以为20倍常数要gg结果ccf的机子没想象中那么233

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define rep(j,k,l) for (int j=k;j<=l;j++)
#define N 2005

using namespace std;
int cl[N][25],sm[N][N],T,k;

int gt(int k,int l){
	
	int ans=0;
	while (k/l){
		
		ans+=k/l;
		k/=l;
		
	}
	return ans;
	
}

int main(){
	
	scanf("%d%d",&T,&k);
	rep(i,1,2001){ //处理i!中各种质因子个数
		
		cl[i][2]=gt(i,2);
		cl[i][3]=gt(i,3);
		cl[i][5]=gt(i,5);
		cl[i][7]=gt(i,7);
		cl[i][11]=gt(i,11);
		cl[i][13]=gt(i,13);
		cl[i][17]=gt(i,17);
		cl[i][19]=gt(i,19);
		
	}
	rep(i,1,2001) rep(j,1,i){ //处理出c(i,j)是否合法 //if提到外面快10倍
		
		if (k==2||k==3||k==5||k==7||k==11||k==13||k==17||k==19){
			
			if (cl[i][k]-cl[i-j][k]-cl[j][k]>=1) sm[i][j]=1;
			else sm[i][j]=0;
			
		}else if (k==4){
			
			if (cl[i][2]-cl[i-j][2]-cl[j][2]>=2) sm[i][j]=1;
			else sm[i][j]=0;
			
		}else if (k==6){
			
			if (cl[i][2]-cl[i-j][2]-cl[j][2]>=1&&
				cl[i][3]-cl[i-j][3]-cl[j][3]>=1) sm[i][j]=1;
			else sm[i][j]=0;
			
		}else if (k==8){
			
			if (cl[i][2]-cl[i-j][2]-cl[j][2]>=3) sm[i][j]=1;
			else sm[i][j]=0;
			
		}else if (k==9){
			
			if (cl[i][3]-cl[i-j][3]-cl[j][3]>=2) sm[i][j]=1;
			else sm[i][j]=0;
			
		}else if (k==10){
			
			if (cl[i][2]-cl[i-j][2]-cl[j][2]>=1&&
				cl[i][5]-cl[i-j][5]-cl[j][5]>=1) sm[i][j]=1;
			else sm[i][j]=0;
			
		}else if (k==12){
			
			if (cl[i][2]-cl[i-j][2]-cl[j][2]>=2&&
				cl[i][3]-cl[i-j][3]-cl[j][3]>=1) sm[i][j]=1;
			else sm[i][j]=0;
			
		}else if (k==14){
			
			if (cl[i][2]-cl[i-j][2]-cl[j][2]>=1&&
				cl[i][7]-cl[i-j][7]-cl[j][7]>=1) sm[i][j]=1;
			else sm[i][j]=0;
			
		}else if (k==15){
			
			if (cl[i][3]-cl[i-j][3]-cl[j][3]>=1&&
				cl[i][5]-cl[i-j][5]-cl[j][5]>=1) sm[i][j]=1;
			else sm[i][j]=0;
			
		}else if (k==16){
			
			if (cl[i][2]-cl[i-j][2]-cl[j][2]>=4) sm[i][j]=1;
			else sm[i][j]=0;
			
		}else if (k==18){
			
			if (cl[i][2]-cl[i-j][2]-cl[j][2]>=1&&
				cl[i][3]-cl[i-j][3]-cl[j][3]>=2) sm[i][j]=1;
			else sm[i][j]=0;
			
		}else if (k==20){
			
			if (cl[i][2]-cl[i-j][2]-cl[j][2]>=2&&
				cl[i][5]-cl[i-j][5]-cl[j][5]>=1) sm[i][j]=1;
			else sm[i][j]=0;
			
		}else if (k==21){
			
			if (cl[i][3]-cl[i-j][3]-cl[j][3]>=1&&
				cl[i][7]-cl[i-j][7]-cl[j][7]>=1) sm[i][j]=1;
			else sm[i][j]=0;
			
		}
		
	}
	rep(i,1,2001) rep(j,1,2001) //二维前辍和
		sm[i][j]=sm[i][j]+sm[i-1][j]+sm[i][j-1]-sm[i-1][j-1];
	while (T--){
		
		int k,l;
		scanf("%d%d",&k,&l);
		printf("%d\n",sm[k][l]);
		
	}
	
}


T2:

参考http://blog.csdn.net/neither_nor/article/details/53300255

我只说一句:奇妙的大自然!

感性理解:先切的长长之后比(对应的)后切的长=开三个队列保存即可

常数较大脑子较抽

#include <bits/stdc++.h>
#define N 100005
#define M 7000005
#define rep(j,k,l) for (int j=k;j<=l;j++)

using namespace std;
int n,m,q,u,v,T,hd1,hd2,hd3,tl1,tl2,tl3;
int a[N],b[M],c[M]; //最初蚯蚓=切掉的前半段=切掉的后半段

bool cmp(const int &x,const int &y){
	
	return x>y;
	
}

int main(){
	
	scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&T);
	double cl=u*1.0/v;
	rep(i,1,n) scanf("%d",&a[i]);
	sort(a+1,a+n+1,cmp);
	rep(i,1,n) a[i]+=q*m;
	hd1=1;hd2=1;hd3=1;
	tl1=n;tl2=0;tl3=0;
	rep(pi,0,m-1){
		
		int mx=0;
		if (hd1<=tl1) mx=max(mx,a[hd1]);
		if (hd2<=tl2) mx=max(mx,b[hd2]);
		if (hd3<=tl3) mx=max(mx,c[hd3]);
		if (hd1<=tl1&&mx==a[hd1]) hd1++;
		else if (hd2<=tl2&&mx==b[hd2]) hd2++;
		else if (hd3<=tl3&&mx==c[hd3]) hd3++;
		mx-=(m-pi)*q;
		b[++tl2]=(int)mx*cl+(m-pi-1)*q;
		c[++tl3]=2*(m-pi-1)*q+mx-b[tl2];
		if ((pi+1)%T==0){
			
			if (pi+1!=T) printf(" ");
			printf("%d",mx);
			
		}
		
	}
	printf("\n");
	rep(i,1,n+m){
		
		int mx=0;
		if (hd1<=tl1) mx=max(mx,a[hd1]);
		if (hd2<=tl2) mx=max(mx,b[hd2]);
		if (hd3<=tl3) mx=max(mx,c[hd3]);
		if (hd1<=tl1&&mx==a[hd1]) hd1++;
		else if (hd2<=tl2&&mx==b[hd2]) hd2++;
		else if (hd3<=tl3&&mx==c[hd3]) hd3++;
		if (i%T==0){
			
			if (i!=T) printf(" ");
			printf("%d",mx);
			
		}
		
	}
	
}

T3:

听说搜索可A?

然后写了半天dfs才发现要写bfs(代码不贴


另一种奇技淫巧:

将点打乱=然后乱搞(不一定要弄出正解的乱搞)=取min

重复上一行字23333遍即可

#include <bits/stdc++.h>
#define rep(j,k,l) for (int j=k;j<=l;++j)
#define N 20
#define eps 0.000001

using namespace std;
double a[N],b[N],c[N][N],d[N][N];
int used[N],nm[N],T,TT,n,ans,kkk[N][N];

void wk(){
	
	rep(i,1,n) used[i]=0;
	int tot=0;
	rep(i,1,n) if (used[i]==0){
		
		used[i]=1;
		rep(j,i+1,n) if (kkk[nm[i]][nm[j]]){
			
			used[j]=1;
			double kk=c[nm[i]][nm[j]];
			double ll=d[nm[i]][nm[j]];
			rep(k,j+1,n) if (kk*a[nm[k]]*a[nm[k]]+ll*a[nm[k]]>b[nm[k]]-eps&&
				kk*a[nm[k]]*a[nm[k]]+ll*a[nm[k]]<b[nm[k]]+eps) used[k]=1;
			break;
			
		}
		tot++;
		
	}
	ans=min(ans,tot);
	
}

int main(){
	
	scanf("%d",&TT);
	for (T=1;T<=TT;T++){
		
		scanf("%d%*d",&n);
		srand(n*2333+T*233+TT*23333);
		rep(i,1,n) scanf("%lf%lf",&a[i],&b[i]),nm[i]=i;
		rep(i,1,n) rep(k,1,n) if (i!=k&&a[k]!=a[i]&&(b[i]*a[k]-b[k]*a[i])/(a[i]*a[k]*(a[i]-a[k]))<0){
			
				kkk[k][i]=kkk[i][k]=1;
				c[k][i]=c[i][k]=(b[i]*a[k]-b[k]*a[i])/(a[i]*a[k]*(a[i]-a[k]));           //抛物线的a
				d[k][i]=d[i][k]=(b[i]*a[k]*a[k]-b[k]*a[i]*a[i])/(a[i]*a[k]*(a[k]-a[i])); //抛物线的b
				
			}else kkk[k][i]=kkk[i][k]=0; //能否组成合法抛物线
		ans=n;
		rep(PI,1,23333){
			
			rep(i,1,n){ //打乱
				
				int poi=rand()%n+1;
				swap(nm[i],nm[poi]);
				
			}
			wk();
			
		}
		printf("%d\n",ans);
		
	}
	
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值