1.题目一:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<queue>
#include<stack>
using namespace std;
//白鸡问题,小于等于n元去买100只鸡,大鸡5元,小鸡 3元,还有1/3元的鸡 求x,y,z 并且以x增大为序列
//想法一 处理这个排序问题的话,就需要用一个结构体数组,把x,y,z存入?然后再排序输出,然后使用一次暴力,然后三次循环
struct M{
int x,y,z;
}Num[100];
bool cmp(M a,M b){
//先比较x,再x相同情况下,比较Y,最后是x
if(a.x!=b.x)
return a.x<b.x;
else if(a.y!=b.y)
return a.y<b.y;
else
return a.z<b.z;
}
int main()
{
int i,j,k,t=0;
int n;
while(scanf("%d",&n)!=EOF){
for(i=0;i<100;i++)//其实这些对于循环的条件都是可以再改进一下的,也可以不用
for(j=0;j<100;j++)
for(k=0;k<100;k++){
if(i+j+k==100&&(3*5*i+3*3*j+1*k)<=3*n){//其实这里主要是把三分之一给化解掉
//在满足这些的条件之下
Num[t].x=i;
Num[t].y=j;
Num[t].z=k;
t++;
}
}
//对这个结构体数组进行排序
sort(Num,Num+t,cmp);
//再进行输出
for(i=0;i<t;i++)
printf("x=%d,y=%d,z=%d\n",Num[i].x,Num[i].y,Num[i].z);
}
}
问题二:BFS
这道题本身是不难的,套用bfs模板就行。可是就是因为自己的一点点小疏忽,把一个x错写成了y,导致找了半天的BUg,苦恼苦恼。。。(大伙们一定要仔细啊!!)
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<queue>
#include<stack>
using namespace std;
//对于BFS来说,需要有队列的参与,每次都是进队,同理这道题的bfs的参数是三个坐标,但是会在队列中多一个时间的坐标,用来表示现在走了多久
//每次进队列的时候,都是之前那个队列出来的时间加一
//然后当然还需要一个三维数组来存xyz,和一个数组来判断有没有被访问过
int map[50][50][50];
bool make[50][50][50];//一个是用以输入,一个是用以判断
int a,b,c,t;//表示的就是坐标位置
//然后创建一个结构体用来存数据
struct M{
int x,y,z,t;//分别代表三个坐标和时间
};
bool judge(int x,int y,int z){
//写一个判断是否可以选这个位置的函数
//把越界单独写出来吧
if(x<0||x>=a||y<0||y>=b||z<0||z>=c)
return false;
if(map[x][y][z]==0&&make[x][y][z]==false)
return true;//如果这个地方是路,并且没有被访问过
return false;
}
//还要写三个数组用来(其实直接用一个二维数组就行)
int stepx[6]={0,0,0,0,1,-1};
int stepy[6]={0,0,1,-1,0,0};
int stepz[6]={1,-1,0,0,0,0};
int BFS(int x,int y,int z,int t){
//这里返回值是int 因为需要返回对应的时间
//首先让他进队吧,可是这个时间怎么算呢,那我的想法就是这里再加一个时间
//先创建一个队列
queue<M> q;
M temp;
temp.x=x;
temp.y=y;
temp.z=z;
temp.t=t;
//然后让这个temp进队列
q.push(temp);
while(!q.empty()){
//在他非空的情况之下,然后删去队头
temp=q.front();//取出对头元素
//这里可以有一个判断
if(temp.x==a-1&&temp.y==b-1&&temp.z==c-1)
return temp.t;
q.pop();
// printf("%d%d%d ",temp.x,temp.y,temp.z);
for(int i=0;i<6;i++){
//开始判断这几个位置
int newx=temp.x+stepx[i];
int newy=temp.y+stepy[i];
int newz=temp.z+stepz[i];
// printf("%d%d%d ",newx,newy,newz);
if(judge(newx,newy,newz)){
//如果这个合理的话,那就,把他的t加一,并且加入队列,这里创建了一个新的结构体,用来加入队列,还要出示话
make[newx][newy][newz]=true;
M gg;
gg.x=newx;
gg.y=newy;
gg.z=newz;//找了半天,问题在这啊!!
gg.t=temp.t+1;//这里是需要注意的
//然后入队
q.push(gg);
}
}
}
return -1;
}
int main()
{
int k,time;
scanf("%d",&k);
while(k--){
scanf("%d%d%d%d",&a,&b,&c,&time);
//开始初始化
for(int i=0;i<a;i++)
for(int j=0;j<b;j++)
for(int z=0;z<c;z++){
scanf("%d",&map[i][j][z]);
make[i][j][z]=false;
}
//然后开始先把第一个位置设置成访问过了
make[0][0][0]=true;
int re=BFS(0,0,0,0);
if(re<=time)
printf("%d\n",re);
else
printf("-1\n");
}
//debug发现从000出发之后,就一个点有效,然后之后就没用了,我知道了,还有一个k没有写!,然后还有问题。。
}
问题四:递归
这题有写过,在hdu100上面
问题五
素数环问题
题目大致意思:
这是一道好题,还是在看了解析之后写出来的,
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<queue>
#include<stack>
using namespace std;
//素数环,大致思路就是:从1出发 然后输入一个值,判断这个值能不能和第一个值相加之后,仍然是素数,如果是的话,那就开始判断下一个
//如果不可以的话,那就回退到前一个
//需要创建一个数组来存当前的输入值,还有一个Bool型数组来判断当前这个可不可以用
int n;
int res[30];
bool has[30];
//再写一个方法判断这个数是不是素数
bool is_su(int x){
if(x<=1)
return false;
for(int i=2;i<x;i++){
if(x%i==0)
return false;
}
return true;
}
//再写一个判断最后一个位置并且输出
void check(){
if(!is_su(res[1]+res[n]))
return ;//如果第一个和最后一个之和不是素数的话,直接回退
for(int i=1;i<n;i++)
printf("%d ",res[i]);
printf("%d",res[n]);
printf("\n");
}
void DFS(int num){
//开始遍历
if(num>1)
if(!is_su(res[num]+res[num-1]))
return ;//直接先判断这个可不可行
if(num==n){
//到了最后一个
check();
return ;
}
//其他情况开始
for(int i=2;i<=n;i++){
if(has[i]==false){
//如果这个点没有被访问过,那就先把他变成访问
has[i]=true;
res[num+1]=i;//这里是+1 不代表num变成了num+1
DFS(num+1);
//开始遍历,遍历完了之后,在把这个位置设置为可以访问
has[i]=false;
}
}
}
int main()
{
int cas=0;//这个就是输出的时候那个case
while(scanf("%d",&n)!=EOF){
//输入这个N
cas++;//每次都加一
//初始化bool
memset(has,false,sizeof(has));
//然后开始判断,把第一个当做访问过了
res[1]=1;
has[1]=true;
printf("Case %d\n",cas);
DFS(1);
}
}
下一题
题目大致意思:
其实就是求连通图的问题,可以用BFS和DFS,而用DFS比较适合,方法就是,在一个数组里,通过一次DFS,把它连通的@全都变成* 然后进行递归,找到剩余的@ 然后继续遍历