AOJ 0033 Ball【DFS】

有一个筒,从A口可以放球,放进去的球可通过挡板DE使其掉进B管或C管里,现有带1-10标号的球按给定顺序从A口放入,问是否有一种控制挡板的策略可以使B管和C管中的球从下往上标号递增。

输入:

第一行输入数据组数N。接下来N行为N组具体数据,每组数据中有10个整数,代表球的放入顺序。

输出:

对于每组数据,若策略存在,输出YES;若不存在,输出NO

解法1:DFS

思路:每次判断当前小球是否大于左边容器的最上端的小球,如果可以就放,否则再去看右边的。一旦发现左右两边都不能放,那就只能判定是NO了。

#include<cstdio>
#include<string>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int INF = 0x7FFFFFFF;
const int maxn = 1e5 + 10;

int a[11],vis[11],flag;

void dfs(int x,int l,int r)
{
    int i;
    if(x==11)return;
    if(flag)return;
    if(a[x]>l)dfs(x+1,a[x],r);
    else if(a[x]>r)dfs(x+1,l,a[x]);
    else{flag=1;return;}
}

int main()
{
  int T,i,j,k;
  scanf("%d",&T);
  while(T--)
  {
    flag=0;
    for(i=1;i<=10;i++)
      scanf("%d",&a[i]);
    memset(vis,0,sizeof(vis));
    dfs(1,0,0);
    if(flag)printf("NO\n");
    else printf("YES\n");
  }
 return 0;
}

解法2:二进制枚举

思路:看作0,1序列

#include<cstdio>
#include<cstring>

int a[15], l[15], r[15], t, i, j, lc, rc, cnt;
bool vis[15], flag;

bool solve()
{
	for (i = 0; i < 1024; ++i)
	{
		memset(l, 0, sizeof(l));
		memset(r, 0, sizeof(r));
		lc = rc = 0;
		for (cnt = 0, j = i; cnt < 10; ++cnt, j >>= 1)
		{
			if (j & 1) l[lc++] = a[cnt];
			else r[rc++] = a[cnt];
		}
		flag = true;
		for (j = 1; j < lc; ++j)
			if (l[j] < l[j - 1])
			{
				flag = false;
				break;
			}
		if (flag)
			for (j = 1; j < rc; ++j)
				if (r[j - 1] > r[j])
				{
					flag = false;
					break;
				}
		if (flag) return true;
	}
	return false;
}

int main()
{
	scanf("%d", &t);
	while (t--)
	{
		memset(vis, 0, sizeof(vis));
		for (i = 0; i < 10; ++i)
			scanf("%d", &a[i]);
		puts(solve() ? "YES" : "NO");
	}
	return 0;
}

bitset增强版

#include <iostream>
#include <bitset>
#include <algorithm>
using namespace std;

int main()
{

	int n;
	cin >> n;
	while (n--)
	{
		int ball[10];

		for (int i = 0; i < 10; ++i)
		{
			cin >> ball[i];
		}

		bitset<10> direction;
		int all = 1024;
		while (all-- > 0)
		{
			direction = static_cast<bitset<10> >(all);
			bool perfect = true;
			int left = 0;
			int right = 0;
			for (int i = 0; i < 10; ++i)
			{
				if (direction[i])
				{
					if (ball[i] > left)
					{
						left = ball[i];
					}
					else
					{
						perfect = false;
						break;
					}
				}
				else
				{
					if (ball[i] > right)
					{
						right = ball[i];
					}
					else
					{
						perfect = false;
						break;
					}
				}
			}
			if (perfect)
			{
				break;
			}
		}

		if (all >= 0)
		{
			cout << "YES" << endl;
		}
		else
		{
			cout << "NO" << endl;
		}
	}

	return 0;
}
时间: 2024-08-13 10:12:40

AOJ 0033 Ball【DFS】的相关文章

poj 3009 Curling 2.0 【DFS】

题意:从2出发,要到达3, 0可以通过,碰到1要停止,并且1处要变成0, 并且从起点开始沿着一个方向要一直前进,直至碰到1(或者3)处才能停止,(就是反射来反射去知道反射经过3).如果反射10次还不能到达3,就输出-1. 策略:深搜. 易错点,方向不容易掌握,并且,出题人把n, m顺序反了. 代码: #include<stdio.h> #include<string.h> int map[25][25]; int ans, n, m; const int dir[4][2] = {

NYOJ 587 blockhouses 【DFS】

blockhouses 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piece of wall. A blockhouse is a small castle th

NYOJ 722 数独 【DFS】+【预处理】

数独 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 数独是一种运用纸.笔进行演算的逻辑游戏.玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行.每一列.每一个3*3宫内的数字均含1-9,不重复. 每一道合格的数独谜题都有且仅有唯一答案,推理方法也以此为基础,任何无解或多解的题目都是不合格的. 有一天hrdv碰到了一道号称是世界上最难的数独的题目,作为一名合格的程序员,哪能随随便便向困难低头,于是他决定编个程序来解决它.. 输入 第一行有一个

poj 1011 Sticks 【DFS】+【剪枝】

题意:有未知根(长度一样)木棒(小于等于n),被猪脚任意的截成n段,猪脚(脑抽了)想知道被截之前的最短长度(我推测猪脚得了健忘症). 这道题光理解题意就花了好久,大意就是任意根被截后的木棒拼到一起,能不能组成s(<=n)根的相同的木棒, 例:数据 9  5 1 2 5 1 2 5 1 2 可以组成最短为6 的(5+1, 2+2+2)3根木棒. 策略:深搜. 不过要是传统的深搜的话,TLE妥妥的.所以要剪枝(所谓剪枝,就是多加几个限制条件). 话不多说直接上代码. 代码1: #include <

HDU1010 Tempter of the Bone 【DFS】+【剪枝】

Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 70895    Accepted Submission(s): 19535 Problem Description The doggie found a bone in an ancient maze, which fascinated him a

nyoj 325 zb的生日 【DP】||【DFS】

两种方法: 第一种:将总数一半当做背包,用总数-2*最多能装的数目就是所求: 第二种:深搜: zb的生日 时间限制:3000 ms  |  内存限制:65535 KB 难度:2 描述 今天是阴历七月初五,acm队员zb的生日.zb正在和C小加.never在武汉集训.他想给这两位兄弟买点什么庆祝生日,经过调查,zb发现C小加和never都很喜欢吃西瓜,而且一吃就是一堆的那种,zb立刻下定决心买了一堆西瓜.当他准备把西瓜送给C小加和never的时候,遇到了一个难题,never和C小加不在一块住,只能

【dfs】hdu 1016 Prime Ring Problem

[dfs]hdu 1016 Prime Ring Problem 题目链接 刚开始接触搜索,先来一道基本题目练练手. 注意对树的深度进行dfs dfs过程中注意回退!!! 素数提前打表判断快一些 参考代码 /*Author:Hacker_vision*/ #include<bits/stdc++.h> #define clr(k,v) memset(k,v,sizeof(k)) using namespace std; const int _max=1e3+10;//素数打表 int n,pr

hdoj 1045 Fire Net 【DFS】

题意:如果两个点要放在同一行或者同一列,那么两个点中间要有一个墙,否则的话只能放一个点,最后问你最多能放几个点. 看了一个星期.. 这道题的解法我还是第一次见,就是逐个逐个的来放置每个点,然后每经过一个点都判断一次,详情看代码 代码: #include <stdio.h> #include <string.h> int ans, n; char map[10][10]; int judge(int lin, int row) { int i; for(i = lin-1; i &g

【DFS】【拓扑排序】【动态规划】Gym - 100642A - Babs&#39; Box Boutique

给你10个箱子,有长宽高,每个箱子你可以决定哪个面朝上摆.把它们摞在一起,边必须平行,上面的不能突出来,问你最多摆几个箱子. 3^10枚举箱子用哪个面.然后按长为第一关键字,宽为第二关键字,从大到小排序. 如果前面的宽大于等于后面的宽,就连接一条边. 形成一张DAG,拓扑排序后跑最长路即可. #include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespa