Loading

noip模拟32

A.Smooth

这道题单是水过去的方法就很多..
最初还幻想着本地把所有数据跑出来然后\(O(1)\)出结果..但是直接把电脑卡死..
正解是使用队列,每次取出\(B\)个队列的队首,比较对首的大小,然后把最小的压进去就可以..

A_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
	#define ll long long int 
	#define ull unsigend ll
	#define re register ll 
	#define lf double
	#define mp(x,y) make_pair(x,y)
	#define lb lower_bound 
	#define ub upper_bound
	#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
	#define Fill(x,y) memset(x,y,sizeof x)
	#define Copy(x,y) memset(x,y,sizeof x)
	inline ll read() {
		ll ss=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0; 
		while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
		return cit?ss:-ss;
	}
} using namespace BSS;

const ll N=20;
ll n,m,s,cnt;
ll x[N],k[(int)1e7+50],pri[N];
queue<ll> f[N];
signed main(){
	 s=read(); n=read();
	 pri[1]=2; pri[2]=3; pri[3]=5;
	 pri[4]=7; pri[5]=11; pri[6]=13;
	 pri[7]=17; pri[8]=19; pri[9]=23;
	 pri[10]=29; pri[11]=31; pri[12]=37;
	 pri[13]=41; pri[14]=43; pri[15]=47;
	 for(re i=1;i<=s;i++){
	 	f[i].push(pri[i]);
	 }
	 ll pos,minn,temp;
	 while(true){
	 	minn=1e18;
	 	for(re j=1;j<=s;j++){
	 		x[j]=f[j].front();
	 		if(x[j]<minn) minn=x[j],pos=j;
	 	}
	 	temp=f[pos].front();  f[pos].pop();
	 	if(k[cnt]==temp) continue;
	 	k[++cnt]=temp; if(cnt>=n) break;
	 	for(re j=pos;j<=s;j++){
	 		f[j].push(temp*pri[j]);
	 	}
	 }
	 printf("%lld",k[n-1]);
	return 0;
}

B.Six

一道很明显的状压..最初想着要写一个\(O(2^{12}*6^2)\)的Dp,后来发现根本做不到..
于是开始想着\(O(2^{24}*6)\)..
八进制压位,记录自己是和哪位数字\(x\)一起进入的状态..
注意记录自己和\(x\)一起进来的时候,要保证这个\(x\)曾经没有出现过,要不然会出现可以转移的状态转移不进来的情况..

B_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
	#define ll long long int 
	#define ull unsigend ll
	#define re register ll 
	#define lf double
	#define mp(x,y) make_pair(x,y)
	#define lb lower_bound 
	#define ub upper_bound
	#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
	#define Fill(x,y) memset(x,y,sizeof x)
	#define Copy(x,y) memset(x,y,sizeof x)
	inline ll read() {
		ll ss=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0; 
		while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
		return cit?ss:-ss;
	}
} using namespace BSS;

const ll mod=1e9+7;
ll m,n,cnt,tot,ans;
ll pri[10],num[10];
ll t[1<<20],dp[1<<20],fst;
inline void Div(){
	ll s=sqrt(n),now=n;
	for(re i=2;i<=s;i++){
		if(now%i==0){
			pri[++cnt]=i;
			while(now%i==0) now/=i,num[cnt]++;
		}
	}
	if(now>1) pri[++cnt]=now,num[cnt]=1;
	return ;
}
signed main(){
	n=read(); ll s=sqrt(n);
	Div();
	fill(t+1,t+(1<<cnt),1); //~~~
	for(re i=0;i<=(1<<cnt)-1;i++){
		for(re j=cnt;j>=1;j--){
			if((i>>(j-1))&1) t[i]=(t[i]*num[j])%mod;
		}
	}
	ll temp,flag,now;
	dp[0]=1;
	for(re i=0;i<=(1<<(cnt*3))-1;i++){
		for(re j=0;j<=(1<<cnt)-1;j++){
			flag=0; now=0;
			for(re k=1;k<=cnt;k++){
				if((j>>(k-1))&1){
					temp=(i>>(k*3-3))&7;
					if(!temp) continue;
					if(temp==7) { flag++; break; }
					if(now and (!(now&(1<<(temp-1))))) { flag++; break; }
					now|=(1<<(temp-1));
				}
			}
			if(flag) continue; temp=i;
			fst=0;
			for(re k=1;k<=cnt;k++){
				if(((j>>(k-1))&1) and (!((i>>(3*k-3))&7))){
					fst=k; break;
				}
			}
			for(re k=1;k<=cnt;k++){
				if((j>>(k-1))&1){
					if((temp>>(k*3-3))&7) temp|=7<<(3*k-3);
					else temp|=fst<<(3*k-3);
				}
			}
			dp[temp]=(dp[temp]+(dp[i]*t[j])%mod)%mod;
		}
		ans=(ans+dp[i])%mod;
	}
	printf("%lld",ans-dp[0]);
	return 0;
}

C.Walker

考场上一开始想着推一推向量,发现不可行..
于是想着要消元..但是始终不能得到正确的解题思路..
这个题将未知数拆解为\(4\)个,然后使用两组数据,从而构造四个方程组,并用概率得到答案..

C_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
	#define ll long long int 
	#define ull unsigend ll
	#define re register ll 
	#define lf double
	#define mp(x,y) make_pair(x,y)
	#define lb lower_bound 
	#define ub upper_bound
	#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
	#define Fill(x,y) memset(x,y,sizeof x)
	#define Copy(x,y) memset(x,y,sizeof x)
	inline ll read() {
		ll ss=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0; 
		while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
		return cit?ss:-ss;
	}
} using namespace BSS;

const ll N=1e5+50;
const lf eps=1e-6;
ll m,n,flag;
lf a[1000][1000],w[1000],ans[1000];
struct I { lf x,y,x2,y2; } p[N];
inline void Guass(){
	ll pos; lf temp;
	for(re i=1;i<=4;i++){
	/*	for(re j=1;j<=4;j++){
			for(re k=1;k<=5;k++){
				printf("%.2lf ",a[j][k]);
			}
			puts("");
		}	
		puts("");
	*/	pos=0;
		for(re j=i;j<=5;j++){ // 枚举列
			for(re k=i;k<=4;k++){
				if(a[k][j]+eps>0 and a[k][j]-eps<0) continue;
				if(k!=i){
					for(re h=1;h<=5;h++){
						swap(a[i][h],a[k][h]);
					}
				}
				pos=j; break;
			}
			if(pos) break;
		}
		if((!pos) or (a[i][pos]<eps and a[i][pos]>-eps)) continue;
		for(re j=i+1;j<=4;j++){
			if(a[j][pos]+eps>0 and a[j][pos]-eps<0) continue;
			temp=a[j][pos]/a[i][pos];
			for(re k=pos;k<=5;k++){
				a[j][k]-=temp*a[i][k];
			}
		}
	}
	for(re i=4;i>=1;i--){
		temp=a[i][5];
		for(re j=i+1;j<=4;j++){
			temp-=a[i][j]*w[j];
		}
		w[i]=temp/a[i][i];
	}
//	printf("%0.2lf %.2lf %.2lf %.2lf\n",w[1],w[2],w[3],w[4]);
//	puts("");
	return ;
}
inline void Check(){
	ll res=0;
	for(re i=1;i<=n;i++){
//		printf("%.3lf %.3lf\n",p[i].x*w[1]-p[i].y*w[2]+w[3],p[i].x*w[2]+p[i].y*w[1]+w[4]);
//		printf("%.3lf %.3lf\n",p[i].x2,p[i].y2); puts("");
		if(p[i].x*w[1]-p[i].y*w[2]+w[3]+eps>p[i].x2)
		if(p[i].x*w[1]-p[i].y*w[2]+w[3]-eps<p[i].x2)
		if(p[i].x*w[2]+p[i].y*w[1]+w[4]+eps>=p[i].y2)
		if(p[i].x*w[2]+p[i].y*w[1]+w[4]-eps<=p[i].y2)
		res++;
	}
	if(res>=((n+1)>>1)){
		flag=1; lf temp;
		ans[1]=atan((lf)(w[2]*1.0/w[1]));
		ans[2]=w[1]*1.0/cos(ans[1]);
		if(ans[2]<=0) ans[2]=w[2]*1.0/sin(ans[1]);
		if(ans[2]<=0) ans[2]=-ans[2];
		ans[1]=acos(w[1]*1.0/ans[2]);
		if(w[2]<0) ans[1]*=-1;
		ans[3]=w[3],ans[4]=w[4];
	}
	return ;
}
signed main(){
//	File(0.in,out);
	srand(time(0));
	ll t1=clock();
	n=read();
	for(re i=1;i<=n;i++){
		scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i].x2,&p[i].y2);
	}
	while(clock()-t1<=900000)
	{
		ll i=rand()%n+1,j=rand()%n+1;
		if(i==j) continue;
		a[1][1]=p[i].x,a[1][2]=-p[i].y;
		a[1][3]=1,a[1][4]=0,a[1][5]=p[i].x2;
		a[2][1]=p[i].y,a[2][2]=p[i].x;
		a[2][3]=0,a[2][4]=1,a[2][5]=p[i].y2;
		a[3][1]=p[j].x,a[3][2]=-p[j].y;
		a[3][3]=1,a[3][4]=0,a[3][5]=p[j].x2;
		a[4][1]=p[j].y,a[4][2]=p[j].x;
		a[4][3]=0,a[4][4]=1,a[4][5]=p[j].y2;
/*		cout<<p[i].x<<" "<<p[i].y<<" "<<p[i].x2<<" "<<p[i].y2<<'\n';
		cout<<p[j].x<<" "<<p[j].y<<" "<<p[j].x2<<" "<<p[j].y2<<'\n';
		cout<<endl;	
*/		Guass(); Check();
		if(flag) break;
	}
	printf("%.10lf\n%.10lf\n%.10lf %.10lf",ans[1],ans[2],ans[3],ans[4]);
	return 0;
}
posted @ 2021-08-09 20:03  AaMuXiiiiii  阅读(25)  评论(0编辑  收藏  举报