“人”比“人”,气死“人”
(为什么“人”要加引号呢?因为这是我们班的一个梗,看不透很正常)
(写之前向老师道个歉,上周作业没写完,所以没写博客,万望老师饶我一命)
来看看我的成绩:
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势在必得。但他今天生病了,头脑很迷糊。不得已,他找到了你帮忙,希望你写个代码帮助他。
样例什么的我也忘了,题面也不一定对,代码也不在手上,我也很无奈啊
不过,这道提的正解我还是记得很清楚的,那就是:筛法!筛法!筛法!