气死“人”的庆生赛

“人”比“人”,气死“人”

(为什么“人”要加引号呢?因为这是我们班的一个梗,看不透很正常)

(写之前向老师道个歉,上周作业没写完,所以没写博客,万望老师饶我一命可怜


来看看我的成绩




1(很明显,题目描述被我改过了(改得不好请见谅)):

hzk(没错,这次我就要黑hzk(应该说这不能算黑))是个聪明的学生,但是他的童鞋kzh是个嫉妒心很强的“人”。为了打败hzk,kzh绞尽脑汁,想了一个他认为很难的问题出来。但他发现自己不会这道题,无法得到正确答案,于是他威胁你(好阔啪QAQ),让你写个程序,算出由“*”围成的闭合曲线中“0”的数目。


样例:

input:

**00*

0****

0*00*

0****


output:

2(中间两个)



老师说这是一个矩形,然后我就交了这样一个代码:

#include<bits/stdc++.h>
using namespace std;
string a[11];
bool b[11][201];
int t=0,tt,s,ans=0;
bool p;
void dfs(int x,int y)
{
	if(p) return;
	if(x==1||x==t||y==0||y==tt)
	{
		s=0;
		p=true;
		return;
	}
	s++;
	b[x][y]=false;
	if(a[x-1][y]=='0'&&b[x-1][y]) dfs(x-1,y);
	if(a[x+1][y]=='0'&&b[x+1][y]) dfs(x+1,y);
	if(a[x][y-1]=='0'&&b[x][y-1]) dfs(x,y-1);
	if(a[x][y+1]=='0'&&b[x][y+1]) dfs(x,y+1);
}
int main()
{
	memset(b,true,sizeof(b));
	while(1)
	{
		cin>>a[++t];
		if(a[t]=="") break;
	}
	t--;
	tt=a[1].size()-1;
	for(int i=1;i<=t;i++)
	for(int j=0;j<=tt;j++)
	if(a[i][j]=='0'&&b[i][j]) 
	{
		s=0;
		p=false;
		dfs(i,j);
		ans+=s;
	}
	cout<<ans; 
	return 0;
}


然后改出来只有六十,结果老师的题解里说:“0”是个矩形emmmmm(虽然好像并没有什么问题(我太蒟了?))


然后改了一下(不止一下。。。),从边缘开始搜,把碰到的全赋成“*”,最后再统计一遍“0”就好啦:

#include<bits/stdc++.h>
using namespace std;
string b[11];
char a[11][201]={};
int t=0,tt,s,ans=0;
void dfs(int x,int y)
{
	a[x][y]='*';
	if (x-1!=0&&a[x-1][y]=='0') dfs(x-1,y);
	if (x+1!=t+1&&a[x+1][y]=='0') dfs(x+1,y);
	if (y+1!=tt&&a[x][y+1]=='0') dfs(x,y+1);
	if (y-1!=-1&&a[x][y-1]=='0') dfs(x,y-1);
}
int main()
{
	while(1)
	{
		cin>>b[++t];
		if(b[t]=="") break;
	}
	t--;
	tt=b[1].size()-1;
	for (int i=1;i<=t;i++)
	for (int j=0;j<=tt;j++)
	a[i][j]=b[i][j];
	for (int i=1;i<=t;i++) if (a[i][0]=='0') dfs(i,0);
	for (int i=1;i<=t;i++) if (a[i][tt]=='0') dfs(i,tt);
	for (int i=0;i<=tt;i++) if (a[1][i]=='0') dfs(1,i);
	for (int i=0;i<=tt;i++) if (a[t][i]=='0') dfs(t,i);
    for (int i=1;i<=t;i++)
    for (int j=0;j<=tt;j++)
    if (a[i][j]=='0') ans++;
	cout<<ans; 
	return 0;
}




2(放心,题目描述全是被我改过的):

kzh没有难住hzk,但是hzk原谅(此原谅非彼原谅,别想歪)了他,两人成了好朋友。一天,两人在一起玩最近很火的“杀逃大:生求地绝”(简称“鸡吃”)。两人开始在“r”点的位置,他们要逃到“a”点。他们每秒能走一步(”.“),但是他们不能穿墙(”#“),如遇到守卫(”x“),他们需要花一秒时间来杀死守卫,才能走到守卫所在的位置。他们想要尽快通关,请问最少要几秒?


样例:

input:

7 8    // 7行8列

# . ##### .

# . a# . . r .

# . . # x . . .

. . # . . # . #

# . . . ## . .

. # . . . . . .

. . . . . . . .



一开始直接写了个dfs,然后加记忆化,结果时间不够了emmmm,直接交了10分的无剪枝dfs:

#include<bits/stdc++.h>
using namespace std;
int a[201][201];
bool b[201][201];
int n,m,x,y,s=0,ans=1000000;
bool p=false;
char ch;
void dfs(int x,int y)
{
	if(a[x][y]==4)
	{
		if(s<ans) ans=s;
		p=true;
	}
	s++;
	if(a[x][y]==3) s++;
	b[x][y]=false;
	if(x>1&&b[x-1][y]) dfs(x-1,y);
	if(x<n&&b[x+1][y]) dfs(x+1,y);
	if(y>1&&b[x][y-1]) dfs(x,y-1);
	if(y<n&&b[x][y+1]) dfs(x,y+1);
	s--;
	if(a[x][y]==3) s--;
	b[x][y]=true;
}
int main()
{
	memset(b,true,sizeof(b));
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		cin>>ch;
		if(ch=='.') a[i][j]=1;
		if(ch=='#') a[i][j]=2,b[i][j]=false;
		if(ch=='x') a[i][j]=3;
		if(ch=='a') a[i][j]=4;
		if(ch=='r') a[i][j]=1,x=i,y=j;
	}
	dfs(x,y);
	if(!p) 
	    cout<<"NO ANSWER";
	else cout<<ans;
	return 0;
}


其实只要再开一个数组,用来统计到当前点的最少的步数,若当前步数已经大于等于目前可行的最少步数,就return,这样就能大大提供效率,就像这样:

        if(s>=b[x][y]) return;
	b[x][y]=s;

然后就是基本的搜索:

        if(x>1) dfs(x-1,y,s+a[x][y]+1);
	if(x<n) dfs(x+1,y,s+a[x][y]+1);
	if(y>1) dfs(x,y-1,s+a[x][y]+1);
	if(y<n) dfs(x,y+1,s+a[x][y]+1);

接着只要判断b[ax][ay]是否有值就行了(rx,ry为hzk和kzh的位置,ax,ay为目标位置):

        memset(b,10,sizeof(b));
        k=b[1][1];
	dfs(rx,ry,0);
	if(k==b[ax][ay])
	    cout<<"NO ANSWER";
	else cout<<b[ax][ay];

完整代码就是这样了:

#include<bits/stdc++.h>
using namespace std;
int a[201][201]={},b[201][201]={},n,m,ax,ay,rx,ry,k;
char ch;
void dfs(int x,int y,int s)
{
	if(a[x][y]==2) return;
	if(s>=b[x][y]) return;
	b[x][y]=s;
	if(x>1) dfs(x-1,y,s+a[x][y]+1);
	if(x<n) dfs(x+1,y,s+a[x][y]+1);
	if(y>1) dfs(x,y-1,s+a[x][y]+1);
	if(y<n) dfs(x,y+1,s+a[x][y]+1);
}
int main()
{
	memset(b,10,sizeof(b));
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		cin>>ch;
		if(ch=='a')
		{
			ax=i;
			ay=j;
		}
		if(ch=='r')
		{
			rx=i;
			ry=j;
		}
		if(ch=='x') a[i][j]=1;
		if(ch=='#') a[i][j]=2;
	}
	k=b[1][1];
	dfs(rx,ry,0);
	if(k==b[ax][ay])
	    cout<<"NO ANSWER";
	else cout<<b[ax][ay];
	return 0;
}





前两题是之前在学校机房写的,但最近QQ被盗, 暂时登不上去,题目自然也不知道了,希望大家体谅

T3依稀记得题目描述(也是改的哈):

hzk的数学老师想考考大家的计算能力,就给大家出了道题:他给了每个人一个数字(我忘了能不能相同),如果A同学的数字能被B同学整除,那么B就是A的福星。他要求每个同学算出自己有多少个福星,最先算出的人可以得到HLJYXXXJS的秘籍——黑皮书。对此,hzk势在必得。但他今天生病了,头脑很迷糊。不得已,他找到了你帮忙,希望你写个代码帮助他。



样例什么的我也忘了,题面也不一定对,代码也不在手上,我也很无奈啊

不过,这道提的正解我还是记得很清楚的,那就是:筛法!筛法!筛法!



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值