码迷,mamicode.com
首页 > 其他好文 > 详细

USTC OJ — 1013 Gizilch(搜索,中等题)

时间:2014-12-12 18:25:04      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   ar   color   os   使用   sp   

1. 题目描述

本题是一道有趣的游戏题,题目背景的描述很是啰嗦,略去不谈。

具体的游戏规则可描述如下:

两个人A和B,A报一个正整数a,B报一个正整数b。其中较大的那个人的游戏角色是擂主,较小的那个人的游戏角色是挑战者。比如:

a = 342, b = 49,显然a > b,那么A就是擂主,B就是挑战者。

那么挑战获胜/失败的规则是什么呢?

我们知道对于任意正整数n,我们都可以把它因子分解,并且可能存在很多中分解形式。比如:

n = 20时,就可以对其因子分解为如下几种形式:

n = 20 * 1 = 10 * 2 = 5 * 4 = 5 * 2 * 2

这里的挑战规则就是:

挑战成功:如果擂主的所有分解形式中,挑战者都存在一种分解,两个分解中存在相同的因子。

挑战失败:如果对于挑战者的所有分解,擂主存在一种分解,该分解中的所有因子都不存在于挑战者的分解中。

2. 算法设计

枚举挑战者的所有因子分解,对每一个分解,枚举擂主的因子分解。

我们用一个标记数组f 来记录某一个因子i 是否已经存在于挑战者的因子分解中,如果存在,f[i] = 1,否则f[i] = 0.

对于f[i] = 1的因子i,我们不可以使用它来分解擂主。

这样依次下去,直到找到一个case:擂主的因子分解顺利完成,那么我们就可以确定擂主获胜,挑战失败。

如果直到枚举完成,也没有找到这样一个case,我们就说擂主落败,挑战成功。

枚举的过程采用深度优先搜索遍历

(注意: 每一个因子只可以出现一次,也就是说因子分解不可以分解成如:20 = 5 * 2 * 2 的形式)

3. AC Code

bubuko.com,布布扣
 1 #include <stdio.h>
 2 #include <string.h>
 3 #define N 105
 4 #define MIN(a, b)   ((a>b)?b:a)
 5 #define MAX(a, b)   ((a>b)?a:b)
 6 
 7 int h, l;
 8 int f[N];
 9 int is_h_can_be_divided, is_h_divided;
10 
11 int dfs(int n);
12 
13 int main()
14 {
15     int a, b;
16     int dfs_ret;
17     int winner;
18 
19     // freopen("in.txt", "r", stdin);
20     while ( EOF != scanf("%d%d", &a, &b) )
21     {
22 
23         l = MIN(a, b);
24         h = MAX(a, b); 
25 
26         // f[i] = 0, 初始时,所有1~n都没有被占用
27         memset(f, 0, sizeof(f));
28         is_h_divided = 0;
29         is_h_can_be_divided = 0;
30 
31         dfs_ret = dfs(l);
32 
33         // 如果h不能按规则分解,h胜利
34         if ( 0 == is_h_can_be_divided )
35             winner = h;
36         // 如果h能按规则分解,但
37         else if ( 1 == is_h_can_be_divided & 1 == dfs_ret )
38             winner = h;
39         else
40             winner = l;
41         printf("%d\n", winner);
42         
43     }
44     return 0;
45 }
46 
47 int dfs(int n)
48 {
49     int n_size;
50     int i;
51 
52     // n == 1时,标识该数分解结束
53     if ( 1 == n )
54     {
55         // is_h_divided 作为h的分解结束标记
56         if ( 0 == is_h_divided )
57         {
58             is_h_can_be_divided = 1;
59             is_h_divided = 1;
60             if ( dfs(h) )
61                 return 1;
62             else                    // h没有分解完,并且无法继续分解
63             {
64                 is_h_divided = 0;
65                 return 0;
66             }
67         }
68         return 1;
69     }
70 
71     // 分解n的过程
72     n_size = 100 < n ? 100 : n;
73     for ( i = 2; i <= n_size; ++i )
74     {
75         // n % i == 0  <=> i是n的因子
76         // f[i]  == 0  <=> i还没有被占用,即保证不会出现20 = 2 * 2 * 5 (i=2)
77         if ( 0 == n % i && 0 == f[i] )
78         {
79             f[i] = 1;
80             if ( dfs(n/i) ) return 1;
81             f[i] = 0;
82         }
83     }
84     return 0;
85 }
View Code

 

USTC OJ — 1013 Gizilch(搜索,中等题)

标签:style   blog   http   io   ar   color   os   使用   sp   

原文地址:http://www.cnblogs.com/nuppt/p/4159996.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!