zoukankan      html  css  js  c++  java
  • 搜索专题练习

    T1:狗哥玩木棒

    现给出一些木棒长度,那么狗哥能否用给出的木棒(木棒全用完)组成一个正方形呢?

    思路:

    既然已经规定木棒全都用上,那么边长就已经定下,就是周长的四分之一

    那么只要考虑剪枝和细节模拟就好了

    同时,我们对木棒进行排序,保证木棒长度有序,短的木棒可以对长的进行填充,进行极大的优化

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=25;
    int n,m;
    int a[N];
    bool used[N],ok;
    int sum;
    inline void clear(){
    	memset(used,0,sizeof used);
    	sum=0;
    	ok=0;
    }
    inline bool cmp(const int &a,const int &b){
    	return a>b;
    }
    inline void search(int pos,int now){
    	if(ok||now>sum) return ;
    	if(now==sum) {now=0;++pos;}
    	if(pos==4) {printf("yes
    ");ok=1;}
    	for(int i=1;i<=m;++i){
    		if(!used[i]){
    			used[i]=1;
    			search(pos,now+a[i]);
    			used[i]=0;
    			if(!now||!(now+a[i])) return ;
    		}
    	}
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i){
    		clear();
    		scanf("%d",&m);
    		for(int i=1;i<=m;++i) {scanf("%d",&a[i]);sum+=a[i];}
    		sum/=4;
    		sort(a+1,a+1+m,cmp);
    		search(0,0);
    		if(!ok) printf("no
    ");
    	}
    }
    

    T2:骑马修栅栏

    John 是一个与其他农民一样懒的人。他讨厌骑马,因此从来不两次经过一个栅栏。

    John 的农场上一共有 m 个栅栏,每一个栅栏连接两个顶点,顶点用 1 到 500 标号(虽然有的农场并没有那么多个顶点)。一个顶点上至少连接 1 个栅栏,没有上限。两顶点间可能有多个栅栏。所有栅栏都是连通的(也就是你可以从任意一个栅栏到达另外的所有栅栏)。John 能从任何一个顶点(即两个栅栏的交点)开始骑马,在任意一个顶点结束。

    你需要求出输出骑马的路径(用路上依次经过的顶点号码表示),使每个栅栏都恰好被经过一次。如果存在多组可行的解,按照如下方式进行输出:如果把输出的路径看成是一个 500 进制的数,那么当存在多组解的情况下,输出 500 进制表示法中最小的一个 (也就是输出第一位较小的,如果还有多组解,输出第二位较小的,以此类推)。

    输入数据保证至少有一个解。

    思路:

    考虑每个点与路径(栅栏)的联系,可以帮助处理题目

    在这种"一笔画问题"中,统计"奇点数"是一种即为广泛的做法

    结合代码理解:

    #include<iostream>
    #include<cstdio>
    #define ci const int &
    using namespace std;
    const int N=505;
    int n,cnt;
    int f[N][N],in[N];
    int rd[N];
    int maxn;
    inline void search(ci now){
    	for(int i=1;i<=maxn;++i)
    		if(f[now][i]) {--f[now][i]; --f[i][now]; search(i);}
    	rd[++cnt]=now;
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i){
    		int a,b;
    		scanf("%d%d",&a,&b);
    		++f[a][b]; ++f[b][a];
    		++in[a]; ++in[b];
    		maxn=max(max(a,b),maxn);
    	} int s=1;
    	for(int i=1;i<=maxn;++i){
    		if(in[i]%2){
    			s=i;
    			break;
    		}
    	} search(s);
    	for(int i=cnt;i>=1;--i)
    		printf("%d
    ",rd[i]);
    	return 0;
    }
    
  • 相关阅读:
    装饰者模式
    Moon.Orm总目录,及常见问题解决方案(有问题直接在这里问,我会立即作答)
    中国IT格局分析
    细说MVC框架的几大困惑
    一天学一个模式_第一天:策略模式
    一天学一个模式_第三天:单例模式
    一天学一个模式_第二天:代理模式
    News: Microsoft Released URL Rewriter 2.0 RTW
    微软一站式示例代码库 20100125 新增代码示例简介
    微软一站式示例代码库 1月小结
  • 原文地址:https://www.cnblogs.com/648-233/p/12678644.html
Copyright © 2011-2022 走看看