20190308搜索考试(水货)

嗯,这个神奇的日子(妇女节,所以祝各位女奆佬女神节快乐!)里,我们进行了搜索的考试,结果。。。不理想啊。。。
好了,现在主要是来简单分析一下。。。
1.简单题(HLOJ#1131)
2.促销(HLOJ#1039)
3.黑洞(HLOJ#1138)
4.激光通讯(HLOJ#1132)
5.流星雨(HLOJ#1140)
以上是考试的五道题目
第一次写这种博客,请各位奆佬不要喷我的宏定义,这是我之前打的板,我用起来会顺一点(然后又懒的修改过来了 ),然后码风可能比较丑,请不要介意呀(所以看懂题解就好了,实在还不会再看代码理解吧 )。

第一题:

emmm,照理说呢,这应该是一道比较简单的签到题(只是呢,送分送的不到位),但我只拿了20分。。。(我真是太弱啦
简单说一下题目
在这里插入图片描述
然后数据范围
在这里插入图片描述
这种题么,就算你是一个初学者,一个一个点加过去,用了long long就有40分了呀。
然而。。。没错,由于对scanf的不熟练,输出明明要用“%lld”,结果我打了“%d”,然后就只有20分了。。。
正确的思路呢,就是把输入的数排个序,把相邻的距离算出来再乘以它使用的次数加起来,否则一个个算过去累加会超时哦(其实就是个递推啦,不算搜索啦)。
GYF专用代码粘上

#include<bits/stdc++.h>
using namespace std;
#define s1(a,n) sort(a+1,a+n+1)
#define s2(a,n) sort(a+1,a+n+1,mycmp)
#define ll long long
#define sg string
#define st struct
#define f1(i,l,r) for(int i=l;i<=r;++i)
#define f2(i,r,l) for(int i=r;i>=l;--i)
#define f3(i,a,b) for(int i=a;i;i=b)
#define me(a,b) memset(a,b,sizeof(a))
#define sf scanf
#define pf printf
ll n,x[3000010],s=0;
bool mycmp(int x,int y)
{
	return x>y;
}
void init()
{
	sf("%lld",&n);
}
void work()
{
	f1(i,1,n)
		sf("%d",&x[i]);
	s1(x,n);
	f1(i,1,n-1)
		s+=((x[i+1]-x[i])*i*(n-i)*2);
}
void print()
{
	pf("%lld",s);
}
int main()
{
	freopen("cowdis.in","r",stdin);
	freopen("cowdis.out","w",stdout);
	init();
	work();
	print();
	return 0;
}

第二题:

这题90分,10分丢的真的超乎意料。。。
题面
在这里插入图片描述
数据范围
在这里插入图片描述
很明显这题目给出就是让我们dfs的嘛,就是标记一下每个数是用还是不用然后数字够了就加起来比较一下够不够,然后枚举超过总数是就可以return了。
所以,我就dfs交了,结果没考虑到double的精度问题,在比较大小的时候用了sum==k(其实应该要用sum-k<0.00000001的),然后一个数据点的数据就少了1。。。(狗啊狗
GYF专用代码粘上

#include<bits/stdc++.h>
using namespace std;
#define s1(a,n) sort(a+1,a+n+1)
#define s2(a,n) sort(a+1,a+n+1,mycmp)
#define ll long long
#define sg string
#define st struct
#define f1(i,l,r) for(int i=l;i<=r;++i)
#define f2(i,r,l) for(int i=r;i>=l;--i)
#define f3(i,a,b) for(int i=a;i;i=b)
#define me(a,b) memset(a,b,sizeof(a))
#define sf scanf
#define pf printf
int n,m,x,y,tot=0;
double ds[30],k;
void init()
{
	sf("%d %d %d %d\n",&n,&m,&x,&y);
	f1(i,1,m)
		ds[i]=1.0/i;
	k=x*1.0;
	k/=y;
}
void work(int ans,int num,double sum)
{
	if(num==n)
	{
		if(abs(sum-k)<0.00000001)
			tot++;
		return;
	}
	if(ans>m) return;
	if(sum>k) return;
	work(ans+1,num+1,sum+ds[ans]);
	work(ans+1,num,sum);
}
void print()
{
	pf("%d",tot);
}
int main()
{
	freopen("cd.in","r",stdin);
	freopen("cd.out","w",stdout);
	init();
	work(1,0,0.0);
	print();
	return 0;
}

第三题:

这又是一道dfs的题,但得分率是这次最低的。
在这里插入图片描述
看完完全没思路有没有?
数据范围在题目中已经有了
其实就是一种种情况枚举过去然后试一试有没有循环,但要注意一次跑的方向统一以及要排序,看是否在同一线上。
但是我。。。在检验的时候出现了一些误差,导致跑小一点的数据时恰好输出对了,只拿了20分。要仔细啊!明明可以做对的啊!
李宗泽和牛玉鑫是谁?别问我,我也不知道,也许是前面几届的某位奆佬吧。
GYF专用代码粘上

#include<bits/stdc++.h>
using namespace std;
#define s1(a,n) sort(a+1,a+n+1)
#define s2(a,n) sort(a+1,a+n+1,mycmp)
#define ll long long
#define sg string
#define st struct
#define f1(i,l,r) for(int i=l;i<=r;++i)
#define f2(i,r,l) for(int i=r;i>=l;--i)
#define f3(i,a,b) for(int i=a;i;i=b)
#define me(a,b) memset(a,b,sizeof(a))
#define sf scanf
#define pf printf
int n,next[20]={},f[20]={},sum=0,k,vis[20];
st wormhole
{
	int x,y;
}hd[20];
bool mycmp(wormhole a,wormhole b)
{
	return (a.y<b.y)||(a.y==b.y&&a.x<b.x);
}
void init()
{
	sf("%d",&n);
	f1(i,1,n)
	    sf("%d %d\n",&hd[i].x,&hd[i].y);
	s2(hd,n);
	f1(i,1,n-1)
    	if(hd[i].y==hd[i+1].y)
			next[i]=i+1;
}
int gg()
{
	f1(i,1,n)
	{
    	k=i;
    	me(vis,0);
		while(next[k]!=0)
		{
			if(vis[next[k]]==1) return 1;
			vis[next[k]]=1;
			k=f[next[k]];
    	}
	}
	return 0;
}
void work(int now)
{
	if(now==n+1)
	{
    	if(gg()==1)
			sum++;
		return;
	}
	if(f[now]!=0)
		work(now+1);
	else
		f1(i,now+1,n)
			if(f[i]==0)
				f[now]=i,f[i]=now,work(now+1),f[now]=f[i]=0;
}
void print()
{
	pf("%d",sum);
}
int main()
{
	freopen("wormhole.in","r",stdin);
	freopen("wormhole.out","w",stdout);
	init();
	work(1);
	print();
	return 0;
}

第四题:

我只是dfs超时了啊。。。
所以这题要用bfs。
在这里插入图片描述
其实一看到这种题目就知道要用bfs吧,但但但是,我不熟不敢用啊。。。所以先打了dfs准备有时间再改成bfs,然后就没时间了。。。
数据范围在题目中已经有了不说了
就是从一个点bfs下去每次都给能到的点附上最小值,搜到目标点就输出并exit(0),结果我第二遍交的时候这个标记还没做好,还以为是方位数组原因改了好久好久。。。(我真的弱啊
哦,还有,开了两个数组来标记能不能走和走过的地方使值达到最小。
GYF专用代码粘上

#include<bits/stdc++.h>
using namespace std;
#define s1(a,n) sort(a+1,a+n+1)
#define s2(a,n) sort(a+1,a+n+1,mycmp)
#define ll long long
#define sg string
#define st struct
#define f1(i,l,r) for(int i=l;i<=r;++i)
#define f2(i,r,l) for(int i=r;i>=l;--i)
#define f3(i,a,b) for(int i=a;i;i=b)
#define me(a,b) memset(a,b,sizeof(a))
#define sf scanf
#define pf printf
int w,h,q=0,f[110][110]={},g[110][110],H=0,T=0,a,b,X,Y,zx[4]={-1,0,0,1},zy[4]={0,1,-1,0};
char ch;
st laser
{
	int x,y,sum;
}fg[10010]; 
bool mycmp(int x,int y)
{
	return x>y;
}
void init()
{
	me(g,-1);
	sf("%d %d\n",&w,&h);
	f1(i,1,h)
	{
		f1(j,1,w)
		{
			sf("%c",&ch);
			if(ch=='C')
				if(q==0)
					f[i][j]=-1,q++,fg[0].x=i,fg[0].y=j,fg[0].sum=0;
				else
					g[i][j]=0,X=i,Y=j;
			if(ch=='.')
				g[i][j]=0;
		}
		getchar();
	}
}
void work()
{
	f1(i,0,3)
	{
		a=fg[0].x+zx[i];
		b=fg[0].y+zy[i]; 
		while(g[a][b]==0)
			f[a][b]=-1,++T,fg[T].x=a,fg[T].y=b,fg[T].sum=0,a+=zx[i],b+=zy[i];
	}
}
void print()
{
	while(H<=T)
	{
		++H;
		if(fg[H].x==X&&fg[H].y==Y)
		{
			pf("%d",fg[H].sum);
			exit(0);
		}
		f1(i,0,3)
		{
			a=fg[H].x+zx[i];
			b=fg[H].y+zy[i];
			while(g[a][b]==0)
			{
				if(f[a][b]==0)
					f[a][b]=-1,++T,fg[T].x=a,fg[T].y=b,fg[T].sum=fg[H].sum+1;
			    a+=zx[i];
				b+=zy[i];
			}
		}
	}
}
int main()
{
	freopen("laser.in","r",stdin);
	freopen("laser.out","w",stdout);
	init();
	work();
	print();
	return 0;
}

第五题:

这题,其实也是bfs,然后我就又方了。。。
题目
在这里插入图片描述
qt是谁?这个我知道,我们班的一位奆佬。为什么写他?因为为了给他长点记性。发生了什么?诶呀,问题怎么这么多,不回答了。。。
数据范围
在这里插入图片描述
模拟如何最快走到绝对安全区域,而且每个时间点还要试一下不能走砸到的地方,貌似很简单吧,结果细节却多的要死,所以好好思考慢慢敲吧,有什么想不到的地方再比较代码看看自己缺在哪,毕竟要留点你们自己想一想嘛(某奆佬:别说了,知道你懒得说明
GYF专用代码粘上

#include<bits/stdc++.h>
using namespace std;
#define s1(a,n) sort(a+1,a+n+1)
#define s2(a,n) sort(a+1,a+n+1,mycmp)
#define ll long long
#define sg string
#define st struct
#define f1(i,l,r) for(int i=l;i<=r;++i)
#define f2(i,r,l) for(int i=r;i>=l;--i)
#define f3(i,a,b) for(int i=a;i;i=b)
#define me(a,b) memset(a,b,sizeof(a))
#define sf scanf
#define pf printf
int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0},n,f[310][310]={},MAP[310][310]={},vis[310][310],x,y,tim,H=0,T=1,xx,yy,X,Y;
st meteor
{
	int x,y,tim;
}q[90010];
bool mycmp(int x,int y)
{
	return x>y;
}
void init()
{
	sf("%d",&n);
    me(vis,10);
	f[0][0]=1; 
	q[1].x=q[1].y=q[1].tim=0;
}
void work()
{
	f1(i,1,n)
    {
   	 	sf("%d %d %d\n",&x,&y,&tim);
   	 	MAP[x][y]=MAP[x+1][y]=MAP[x][y+1]=1;
   	 	vis[x][y]=min(vis[x][y],tim);
   	 	vis[x+1][y]=min(vis[x+1][y],tim);
   	 	vis[x][y+1]=min(vis[x][y+1],tim);
   	 	if(x>=1)
			vis[x-1][y]=min(vis[x-1][y],tim),MAP[x-1][y]=1;
   	 	if(y>=1)
			vis[x][y-1]=min(vis[x][y-1],tim),MAP[x][y-1]=1;
    }
}
void print()
{
	while(H<=T)
    {
    	++H;
		xx=q[H].x;
   		yy=q[H].y;
   		if(!MAP[xx][yy])
   	 	{
   	    	pf("%d",q[H].tim);
	    	return;
	    }
		f1(i,0,3)
		{
	  		X=xx+dx[i];
	  		Y=yy+dy[i];
	  		if(X<0||Y<0||f[X][Y]) continue;
	  		if(vis[X][Y]>q[H].tim+1)
	  			f[X][Y]=1,++T,q[T].x=X,q[T].y=Y,q[T].tim=q[H].tim+1;	
	    } 
    }
	pf("-1");
}
int main()
{
	freopen("meteor.in","r",stdin);
   freopen("meteor.out","w",stdout);
   init();
	work();
	print();
   return 0;
} 

Over,感谢各位奆佬捧场,GYF感激不尽(orz)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值