暑假搜索专题1(搜索)补题

A - Fox And Two Dots(CF510B)

最后突然发现有个特判,为此t了好几发

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
int m,n,sx,sy;
char ma[55][55];
int vis[55][55];
int flag;
int x[4]={0,0,1,-1},y[4]={1,-1,0,0};
void dfs(char q,int cnt,int s,int t){
    if(cnt>=4&&sx==s&&sy==t){
        flag=1;
        return;
    }
    if(flag)    return;
    for(int i=0;i<4;i++){
        if(flag) break;
        int xx=x[i]+s,yy=y[i]+t;
        if(xx>=0&&xx<m&&yy>=0&&yy<n&&!vis[xx][yy]&&ma[s][t]==ma[xx][yy]){
            vis[xx][yy]=1;
            dfs(q,cnt+1,xx,yy);
            if(flag)    break;
            vis[xx][yy]=0;
        }
    }
}
int main(){
    scanf("%d%d",&m,&n);
    for(int i=0;i<m;i++)
            scanf(" %s",ma[i]);
    flag=0;
    memset(vis,0,sizeof(vis));
    for(int i=0;i<m;i++)
    for(int j=0;j<n;j++){
        if(ma[i][j]==ma[i+1][j]&&ma[i][j]==ma[i][j+1]&&ma[i][j]==ma[i+1][j+1]){
            printf("Yes\n");
            return 0;
        }
    }
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            if(flag)    break;
            sx=i,sy=j;
            dfs(ma[i][j],0,i,j);
        }
        if(flag)    break;
    }
    if(flag)    printf("Yes\n");
    else        printf("No\n");
    return 0;
}

B题 N皇后问题(HDU2553)

做过的一道经典题,不过测试的时候我tm卡了,好久才想起来本地打表,脑子瓦特了

做过的一道经典题,不过测试的时候我tm卡了,好久才想起来本地打表,脑子瓦特了
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
/*
int a[11],m,vis[11],ans;
bool check(int l,int i){
    for(int j=0;j<l;j++)
        if(l-j==i-a[j]||j-l==i-a[j])   return 0;
    return 1;
}
void dfs(int n){
    if(n==m)  ans++;
    if(n>m)     return ;
    for(int i=0;i<m;i++){
        if(!vis[i]&&check(n,i)){
            a[n]=i;
            vis[i]=1;
            //printf("%d %d \n",n,i);
            dfs(n+1);
            vis[i]=0;
        }
    }
}*/
int ans[15]={0,1,0,0,2,10,4,40,92,352,724},m;
int main(){
    while(scanf("%d",&m)!=EOF){
        if(m==0)    break;
        /*ans=0;
        memset(vis,0,sizeof(vis));
        dfs(0);*/
        printf("%d\n",ans[m]);
    }
    return 0;
}

C Prime Ring Problem(HDU1016)

又是做过的题目,但是又卡好久了,难受,没看到每个样例之间要输出一个换行。。。。。。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
int m,vis[30],s[30],ans=0,cnt=1;
int pr[50]={2,3,5,7,11,13,17,19,23,29,31,37,41,43};
bool ok(int k){
    for(int i=0;i<=15;i++)
        if(k==pr[i])    return 1;
    return 0;
}
void dfs(int a){
    if(a==m){
        for(int j=0;j<m-1;j++)
                printf("%d ",s[j]);
            printf("%d\n",s[m-1]);
    }
    if(a>=m)     return ;
    for(int i=2;i<=m;i++){
        if(!vis[i]&&a<m-1&&ok(s[a-1]+i)){
            vis[i]=1;
            s[a]=i;
            dfs(a+1);
            vis[i]=0;
        }
        if(!vis[i]&&a==m-1&&ok(s[a-1]+i)&&ok(i+1)){
            vis[i]=1;
            s[a]=i;
            dfs(a+1);
            vis[i]=0;
        }
    }
}
int main(){
    while(scanf("%d",&m)!=EOF){
        memset(vis,0,sizeof(vis));
        memset(s,0,sizeof(s));
        printf("Case %d:\n",cnt++);
        if(m==1)    {
            printf("\n");
            continue;
        }
        vis[1]=0;
        s[0]=1;
        dfs(1);
        printf("\n");
    }
    return 0;
}

D - Square(HDU1518)

Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Description

Given a set of sticks of various lengths, is it possible to join them end-to-end to form a square?

Input

The first line of input contains N, the number of test cases. Each test case begins with an integer 4 <= M <= 20, the number of sticks. M integers follow; each gives the length of a stick - an integer between 1 and 10,000.

Output

For each case, output a line containing “yes” if is is possible to form a square; otherwise output “no”.

Sample Input

3
4 1 1 1 1
5 10 20 30 40 50
8 1 7 2 6 4 4 3 5

Sample Output

yes
no
yes

题意:这题审题出现了错误,我以为是从n根木棍里面去找能不能凑出一个正方形,实际上是让你判断这n根木棍是不是来自于一个正方形,因此边长已经确定了,选取木棍的个数已经确定了,是我想复杂了.


#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
int flag,m,n,s[30],vis[30],sum;
int dfs(int k,int num,int mas){//不传参数k的话会超时
    if(mas==sum/4){
		k=0;
		mas=0;
		num++;
		if(num==4)
			return 1;
	}
	if(mas>sum/4)   return 0;
    for(int i=k;i<n;i++)
        if(!vis[i]){
            vis[i] = 1;
			if((mas+s[i] <= sum )&&dfs(k+1,num,mas+s[i]))
				return 1;
			vis[i] = 0;
        }
    return 0;
}
int main(){
    scanf("%d",&m);
    while(m--){
        scanf("%d",&n);
        sum=0;
        for(int i=0;i<n;i++){
            scanf("%d",&s[i]);
            sum+=s[i];
        }
        memset(vis,0,sizeof(vis));
        flag=0;
        if(sum%4==0)
            flag=dfs(0,0,0);
        if(flag)    printf("yes\n");
        else            printf("no\n");
    }
    return 0;
}

E - A计划(HDU 2102)

Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u

Description

可怜的公主在一次次被魔王掳走一次次被骑士们救回来之后,而今,不幸的她再一次面临生命的考验。魔王已经发出消息说将在T时刻吃掉公主,因为他听信谣言说吃公主的肉也能长生不老。年迈的国王正是心急如焚,告招天下勇士来拯救公主。不过公主早已习以为常,她深信智勇的骑士LJ肯定能将她救出。
现据密探所报,公主被关在一个两层的迷宫里,迷宫的入口是S(0,0,0),公主的位置用P表示,时空传输机用#表示,墙用*表示,平地用.表示。骑士们一进入时空传输机就会被转到另一层的相对位置,但如果被转到的位置是墙的话,那骑士们就会被撞死。骑士们在一层中只能前后左右移动,每移动一格花1时刻。层间的移动只能通过时空传输机,且不需要任何时间。

Input

输入的第一行C表示共有C个测试数据,每个测试数据的前一行有三个整数N,M,T。 N,M迷宫的大小NM(1 <= N,M <=10)。T如上所意。接下去的前NM表示迷宫的第一层的布置情况,后N*M表示迷宫第二层的布置情况。

Output

如果骑士们能够在T时刻能找到公主就输出“YES”,否则输出“NO”。

Sample Input

1
5 5 14
S*#*.
.#…

****.
…#.

.P
#.

**
.
*.#…

Sample Output

YES

没有注意到到达#时是瞬间传送去对应的层数,wa了好多发,阅读理解太菜了我。。。。

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
struct node{
    int x,y,z,t;
};
char ma[3][12][12];
int vis[3][12][12];
int dis[4][3]={{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};
int r,c,sx,sy,sz,T;
bool check(int a,int b,int t){
    if(a>=0&&a<2&&b>=0&&t>=0&&b<r&&t<c&&(ma[a][b][t]=='.'||ma[a][b][t]=='P'))   return 1;
    else    return 0;
}
int bfs(){
    memset(vis,0,sizeof(vis));
    queue<node>q;
    node st,tem;
    st.x=sx;
    st.y=sy;
    st.z=sz;
    st.t=0;
    vis[sx][sy][sz]=1;
    q.push(st);
    while(!q.empty()){
        st=q.front();
        if(ma[st.x][st.y][st.z]=='P'&&st.t<=T)      return 1;
        if(st.t>T)        return 0;
        q.pop();
        for(int i=0;i<4;i++){
            tem.x=st.x+dis[i][0];
            tem.y=st.y+dis[i][1];
            tem.z=st.z+dis[i][2];
            if(ma[tem.x][tem.y][tem.z]=='#')
                tem.x=!tem.x;
            if(!vis[tem.x][tem.y][tem.z]&&check(tem.x,tem.y,tem.z)){
                tem.t=st.t+1;
                q.push(tem);
                vis[tem.x][tem.y][tem.z]=1;
            }
        }
    }
    return 0;
}
int main(){
    int s;
    scanf("%d",&s);
    while(s--){
        scanf("%d %d %d",&r,&c,&T);
        for(int i=0;i<2;i++){
            for(int j=0;j<r;j++){
                getchar();
                scanf("%s",ma[i][j]);
            }
            getchar();
        }
        sx=0;
        sy=0;
        sz=0;
        if(bfs())   printf("YES\n");
        else        printf("NO\n");
    }
    return 0;
}

F - Nightmare(HDU 1072)

Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u

Description

Ignatius had a nightmare last night. He found himself in a labyrinth with a time bomb on him. The labyrinth has an exit, Ignatius should get out of the labyrinth before the bomb explodes. The initial exploding time of the bomb is set to 6 minutes. To prevent the bomb from exploding by shake, Ignatius had to move slowly, that is to move from one area to the nearest area(that is, if Ignatius stands on (x,y) now, he could only on (x+1,y), (x-1,y), (x,y+1), or (x,y-1) in the next minute) takes him 1 minute. Some area in the labyrinth contains a Bomb-Reset-Equipment. They could reset the exploding time to 6 minutes.

Given the layout of the labyrinth and Ignatius’ start position, please tell Ignatius whether he could get out of the labyrinth, if he could, output the minimum time that he has to use to find the exit of the labyrinth, else output -1.

Here are some rules:

  1. We can assume the labyrinth is a 2 array.
  2. Each minute, Ignatius could only get to one of the nearest area, and he should not walk out of the border, of course he could not walk on a wall, too.
  3. If Ignatius get to the exit when the exploding time turns to 0, he can’t get out of the labyrinth.
  4. If Ignatius get to the area which contains Bomb-Rest-Equipment when the exploding time turns to 0, he can’t use the equipment to reset the bomb.
  5. A Bomb-Reset-Equipment can be used as many times as you wish, if it is needed, Ignatius can get to any areas in the labyrinth as many times as you wish.
  6. The time to reset the exploding time can be ignore, in other words, if Ignatius get to an area which contain Bomb-Rest-Equipment, and the exploding time is larger than 0, the exploding time would be reset to 6.

Input

The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow.
Each test case starts with two integers N and M(1<=N,Mm=8) which indicate the size of the labyrinth. Then N lines follow, each line contains M integers. The array indicates the layout of the labyrinth.
There are five integers which indicate the different type of area in the labyrinth:
0: The area is a wall, Ignatius should not walk on it.
1: The area contains nothing, Ignatius can walk on it.
2: Ignatius’ start position, Ignatius starts his escape from this position.
3: The exit of the labyrinth, Ignatius’ target position.
4: The area contains a Bomb-Reset-Equipment, Ignatius can delay the exploding time by walking to these areas.

Output

For each test case, if Ignatius can get out of the labyrinth, you should output the minimum time he needs, else you should just output -1.

Sample Input

3
3 3
2 1 1
1 1 0
1 1 3
4 8
2 1 1 0 1 1 1 0
1 0 4 1 1 0 4 1
1 0 0 0 0 0 0 1
1 1 1 4 1 1 1 3
5 8
1 2 1 1 1 1 1 4
1 0 0 0 1 0 0 1
1 4 1 0 1 1 0 1
1 0 0 0 0 3 0 1
1 1 4 1 1 1 1 1

Sample Output

4
-1
13

做的时候嫌英文太长了看都没看QAQ

补题:BFS

要求在6步内走出迷宫,比最普通的迷宫多了一个存档点,走到这个点时可以将已走步数重置为0 问能不能走出去,要多少步

#include<stdio.h>
#include<string.h>
#include<queue>b
using namespace std;
#define inf 0x3f3f3f3f
struct node{
    int x,y,sum,step;
};
int m,n;
node st,ed;
int x[4]={0,0,1,-1},y[4]={1,-1,0,0};
int ma[10][10];
int time[10][10];
int bfs(){
    queue<node>q;
    q.push(st);
    while(!q.empty()){
        st=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            ed.x=st.x+x[i],ed.y=st.y+y[i],ed.step=st.step+1,ed.sum=st.sum+1;
            if(ed.sum<6&&ed.x<m&&ed.x>=0&&ed.y>=0&&ed.y<n){
                if(ma[ed.x][ed.y]==4&&time[ed.x][ed.y]>ed.sum){//再次到达这点的时间一定要更小,此点不能是墙和起点
                    time[ed.x][ed.y]=0;
                    ed.sum=0;
                    q.push(ed);
                }
                else if(ma[ed.x][ed.y]==1){
                    q.push(ed);
                    time[ed.x][ed.y]=ed.sum;
                }
                else if(ma[ed.x][ed.y]==3){
                    return ed.step;
                }
            }
        }
    }
    return -1;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d %d",&m,&n);
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++){
                scanf("%d",&ma[i][j]);
                if(ma[i][j]==2)  st.x=i,st.y=j;
            }
        memset(time,inf,sizeof(time));
        st.step=0,st.sum=0;
        printf("%d\n",bfs());
    }
    return 0;
}

G - The Great Mixing (CF798E)

Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u
Submit

Status

Practice

CodeForces 789E
use MathJax to parse formulas
Description

Sasha and Kolya decided to get drunk with Coke, again. This time they have k types of Coke. i-th type is characterised by its carbon dioxide concentration . Today, on the party in honour of Sergiy of Vancouver they decided to prepare a glass of Coke with carbon dioxide concentration . The drink should also be tasty, so the glass can contain only integer number of liters of each Coke type (some types can be not presented in the glass). Also, they want to minimize the total volume of Coke in the glass.

Carbon dioxide concentration is defined as the volume of carbone dioxide in the Coke divided by the total volume of Coke. When you mix two Cokes, the volume of carbon dioxide sums up, and the total volume of Coke sums up as well.

Help them, find the minimal natural number of liters needed to create a glass with carbon dioxide concentration . Assume that the friends have unlimited amount of each Coke type.

Input

The first line contains two integers n, k (0 ≤ n ≤ 1000, 1 ≤ k ≤ 106) — carbon dioxide concentration the friends want and the number of Coke types.

The second line contains k integers a1, a2, …, ak (0 ≤ ai ≤ 1000) — carbon dioxide concentration of each type of Coke. Some Coke types can have same concentration.

Output

Print the minimal natural number of liter needed to prepare a glass with carbon dioxide concentration , or -1 if it is impossible.

Sample Input

Input
400 4
100 300 450 500
Output
2
Input
50 2
100 25
Output
3
Hint

In the first sample case, we can achieve concentration using one liter of Coke of types and : .

In the second case, we can achieve concentration using two liters of type and one liter of type: .
题意:已知m种浓度为a1,a2……am的二氧化碳,如何配置为指定浓度为n的二氧化碳

即(a1+a2+……+ak)/k =n (a1,a2,ak为任取的m种浓度的一种或多种

变形 a1+a2+……+ak=k*n

(a1-n)+(a2-n)+……(ak-n)= 0;

由于浓度都在区间【0,1000】,所以-1000<=(ak-n)<=1000

即可由此进行搜索
补题:BFS

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int m,n,k,num,flag,step[2222];
int a[2005],vis[2006];
int bfs(){
    queue<int>q;
    q.push(1000);
    while(!q.empty()){
        int tem=q.front();
        //printf("%d %d\n",step[tem],tem);
        q.pop();
        if(tem==1000&&step[tem]!=0)      return step[tem];
        for(int i=0;i<num;i++){
            if(tem+a[i]-n>=0&&tem+a[i]-n<=2000&&step[tem+a[i]-n]==0){
                step[tem+a[i]-n]=step[tem]+1;
                q.push(tem+a[i]-n);
            }
        }
    }
    return -1;
}
int main(){
    scanf("%d %d",&n,&m);
    memset(step,0,sizeof(step));
    for(int i=0;i<m;i++){
        scanf("%d",&k);
        if(!vis[k])   a[num++]=k;//不重复的记录浓度信息,
        if(n==k)      flag=1;
        else          vis[k]=1;
    }
    if(flag)    printf("1\n");
    else    printf("%d\n",bfs());
    return 0;
}
总结:不注意细节,阅读有大问题
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值