AOJ 0033 ball+AOH 0118Property Distribution (DFS)

Description

タナカ氏が HW アールの果樹園を残して亡くなりました。果樹園は東西南北方向に H×W の区画に分けられ、区画ごとにリンゴ、カキ、ミカンが植えられています。タナカ氏はこんな遺言を残していました。

果樹園は区画単位でできるだけ多くの血縁者に分けること。ただし、ある区画の東西南北どれかの方向にとなりあう区画に同じ種類の果物が植えられていた場合は、区画の境界が分からないのでそれらは 1 つの大きな区画として扱うこと。

例えば次のような 3x10 の区画であれば(リはリンゴ、カはカキ、ミはミカンを表す)

同じ樹がある区画の間の境界を消すと次のようになり、

結局 10 個の区画、つまり 10 人で分けられることになります。 雪が降って区画の境界が見えなくなる前に分配を終えなくてはなりません。あなたの仕事は果樹園の地図を もとに分配する区画の数を決めることです。ということで、果樹園の地図を読み込み、分配を受けら れる血縁者の人数を出力して終了するプログラムを作成してください。ただし、果樹園の地図は W 文字×H 行の文字列として与えられます。この文字列には、リンゴを表す@、カキを表す#、ミカンを表す*、の 3 文字しか使われていません。

Input

複数のデータセットが与えられます。各データセットは空白で区切られたH Wを含む行から始まり、続いてH × Wの文字が与えられます。入力はゼロが2つの行で終わります。

H, W は100以下です。

Output

各データセットごとに、分配を受ける人数を1行に出力してください。

Sample Input

10 10
####*****@
@#@@@@#*#*
@##***@@@*
#****#*@**
##@*#@@*##
*@@@@*@@@#
***#@*@##*
*@@@*@@##@
*@*#*@##**
@****#@@#@
0 0

Output for the Sample Input

33

日文的题目啊,第一次做,高大上高大上!!

然后我就看了别人的翻译= =,题目很简单:在H * W的矩形果园里有苹果、梨、蜜柑三种果树, 相邻(上下左右)的同种果树属于同一个区域,给出果园的果树分布,求总共有多少个区域。 (原题的样图中苹果为リ,梨为カ,蜜柑为ミ,

图中共10个区域) 。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
char map[105][105];
int w,h,t,dir[4][2]={0,1,0,-1,1,0,-1,0},vis[105][105];
void dfs(int x,int y)
{
   	int i;
   	if(x<=0||y<=0||x>w||y>h)return;
  //  printf("%d %d\n",x,y);
   	for(i=0;i<4;i++)
   	{
	   	int fx=x+dir[i][0];
	   	int fy=y+dir[i][1];
	   	if(!vis[fx][fy]&&map[fx][fy]==map[x][y])
	   	{
	   		vis[fx][fy]=1;
	   		dfs(fx,fy);
	   	}
	   }
	//   printf("1 %d %d \n",x,y);
}
int main()
{
   int i,j,k;
   while(scanf("%d%d",&w,&h)!=EOF)
   {
   	t=0;
   	if(w==0&&h==0)break;
   	memset(vis,0,sizeof(vis));
   	for(i=1;i<=w;i++)
   	for(j=1;j<=h;j++)
   	{
	   	cin>>map[i][j];
	   }

	   for(i=1;i<=w;i++)
	   for(j=1;j<=h;j++)
	   if(!vis[i][j]){
	    vis[i][j]=1;

   		t++;dfs(i,j);
   	}
	 printf("%d\n",t);
   }
   return 0;
}

Description

図のように二股に分かれている容器があります。1 から10 までの番号が付けられた10 個の玉を容器の開口部 A から落とし、左の筒 B か右の筒 C に玉を入れます。板 D は支点 E を中心に左右に回転できるので、板 D を動かすことで筒 B と筒 C のどちらに入れるか決めることができます。開口部 A から落とす玉の並びを与えます。それらを順番に筒 B 又は筒 Cに入れていきます。このとき、筒 B と筒 C のおのおのが両方とも番号の小さい玉の上に大きい玉を並べられる場合は YES、並べられない場合は
NO と半角大文字で出力して終了するプログラムを作成してください。ただし、容器の中で玉の順序を入れ替えることはできないものとします。また、続けて同じ筒に入れることができるものとし、筒 B, C ともに10 個の玉がすべて入るだけの余裕があるとします。

Input

複数のデータセットが与えられます。1行目にデータセット数 N が与えられます。つづいて、N 行のデータセットが与えられます。各データセットに 10 個の番号が与えられます。左から1番目の玉の番号、2番目の玉の番号、、、といった順番です。

Output

各データセットに対して、YES または NO を出力して下さい。

Sample Input

2
3 1 4 2 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1

Output for the Sample Input

YES
NO

这题也比较简单,题目是说:十个球按给定顺序从图中所示容器中下落,然后挡板可以让球落在左边或者右边,问给定球的顺序,是否存在两边从低到高都是递增的情况。所以可以想到,每次判断当前小球是否大于左边容器的最上端的小球,如果可以就放,否则再去看右边的。一旦发现左右两边都不能放,那就只能判定是NO了。

#include<stdio.h>

#include<string.h>

int a[13],vis[13],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;

}

两题都是简单的DFS,不需要回溯。

时间: 2024-08-28 16:26:05

AOJ 0033 ball+AOH 0118Property Distribution (DFS)的相关文章

AOJ 0033 Ball【DFS】

有一个筒,从A口可以放球,放进去的球可通过挡板DE使其掉进B管或C管里,现有带1-10标号的球按给定顺序从A口放入,问是否有一种控制挡板的策略可以使B管和C管中的球从下往上标号递增. 输入: 第一行输入数据组数N.接下来N行为N组具体数据,每组数据中有10个整数,代表球的放入顺序. 输出: 对于每组数据,若策略存在,输出YES:若不存在,输出NO 解法1:DFS 思路:每次判断当前小球是否大于左边容器的最上端的小球,如果可以就放,否则再去看右边的.一旦发现左右两边都不能放,那就只能判定是NO了.

AOJ -0033 Ball(DFS)

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=22516 一道需要思考的搜索题. 题意:十个球按给定顺序从图中所示容器中下落,然后挡板可以让球落在左边或者右边,问给定球的顺序,是否存在两边从低到高都是递增的情况. 解1:只要给定的球能够分成两个递增的序列,那么一定是满足条件的,用dfs可以找出以第一个球为首的递增序列,把其标记,然后判断剩下的球是不是也构成一个递增序列. 1 #include <iostream> 2 #

AOJ 0033 Ball 题解 《挑战程序设计竞赛》

题目:Aizu - 0033 思路:二进制枚举,用了昨天学到的2^N以及与运算方法枚举. 1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 5 using namespace std; 6 7 int n; 8 int ball[10]; 9 vector<int> l; 10 vector<int> r; 11 12 bool solve() { 13 bool

AOJ 0033 Ball

题意 题目我截图下来了,我大致解释下.有编号1到10共10个球,从上方丢下去,入口处可以选择进入左边或者右边,最后10个球全部落下去后如果左右两侧都是从小到大的顺序,则输出YES:否则输出NO. 代码 一开始我先测试了一下自己理解的题意是不是对的: #include <iostream> #include <vector> using namespace std; int main() { vector<int> left; vector<int> righ

AOJ 0033

Ball 可以用dfs,不过发现用一个循环就可以搞定. 1 #include <iostream> 2 using namespace std; 3 int a[11], n; 4 int main(){ 5 cin >> n; 6 while(n--){ 7 for(int i = 0; i < 10; i ++) cin >> a[i]; 8 int c = 0, b = 0, flag = 1; 9 for(int i = 0; i < 10; i +

POJ 1979 POJ 3009 AOJ 0033 AOJ 0118 [搜索类题目][0033贪心模拟]

/** POJ 1979 BFS */ #include <stdio.h> #include <string.h> #include <iostream> #include <queue> using namespace std; const int N = 20 + 5; int mp[N][N]; int sx,sy; int n, m; int vis[3000]; int dirx[] = {0, 1, 0, -1}; int diry[] = {

nomasp 博客导读:Android、UWP、Algorithm、Lisp(找工作中……

Profile Introduction to Blog 您能看到这篇博客导读是我的荣幸.本博客会持续更新.感谢您的支持.欢迎您的关注与留言.博客有多个专栏,各自是关于 Android应用开发 .Windows App开发 . UWP(通用Windows平台)开发 . SICP习题解 和 Scheme语言学习 . 算法解析 与 LeetCode等题解 .而近期会加入的文章将主要是算法和Android.只是其他内容也会继续完好. About the Author 独立 Windows App 和

uva 11853 Paintball dfs找连通块

题意: 给出一个矩形湖, 湖里面有一些圆形地小岛, 问能否从左岸乘船到达右岸,如果能,找出最上面的起点和终点. 题解: 如果能从左岸到达右岸,那么一定不能存在一个连通的岛屿从上岸连到下岸, 所以直接从上到下做dfs,判断是否存在从上岸到下岸地连通块,完成判断.那么接下来就是如何找出最上方地点了,画画图便发现,对于起点,如果存在跨越上岸和左岸地连通岛屿,那么起点一定只能在左岸地交点下方,所以,只需在dfs的过程中更新起点和终点位置即可. 代码: #include <queue> #include

挑战程序设计竞赛 2.1 最基础的“穷竭搜索”

[Summarize] 1.划分为两堆的无序模型可以利用二进制枚举, 而划分为两堆的有序模型可以枚举全排列取定长 2.当搜索终态唯一时可考虑逆向搜索 POJ 1979:Red and Black /* 一个矩形的屋子里有一个人,他可以踩黑格子,但是不能踩红格子, 他现在站在一个黑格子上,告诉你房间的布局, 这个人可以向上下左右四个方向移动,问这个人最多能到达的格子数 */ #include <cstdio> #include <cstring> using namespace st