【hihocoder1255 Mysterious Antiques in Sackler Museum】构造 枚举

简介: 2015北京区域赛现场赛第2题。 题面:http://media.hihocoder.com/contests/icpcbeijing2015/problems.pdf OJ链接:http://hihocoder.com/problemset/problem/1255 题意:给4个矩形的宽和高,问能否选出3个拼成一个大矩形。

2015北京区域赛现场赛第2题。

题面:http://media.hihocoder.com/contests/icpcbeijing2015/problems.pdf

OJ链接:http://hihocoder.com/problemset/problem/1255

题意:给4个矩形的宽和高,问能否选出3个拼成一个大矩形。

解法:可以称之为构造、暴力、枚举、搜索

当时场上写了个很无脑的版本,变量a,b,c一个个枚举,没有可扩展性。

其实稍加分析,把判断和枚举的两个模块独立开来:

  1. 判断的过程每次都只针对一个由3*2个数构成的序列,实现比较直观,只有两种构造方法,见代码;

  2. 一共有(4!) * (2^3)个不同的序列,所以枚举的过程可转化为两个独立的子问题:求4个数的全排列和3个二值量所有取值向量。

  全排列可借助next_permutation方便地得到。k个二值量的所有取值向量可以通过[0,2^k]的整数的二进制表示得到。

  由于是二值量,直接先swap再交换回来即可。注意swap传引用。

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 struct Rec{
 6     int w, h;
 7     Rec& operator = (Rec& r){
 8         w = r.w;
 9         h = r.h;
10         return *this;
11     }
12 }rec[4];
13 
14 int n;
15 int index[4];
16 
17 void swap(Rec& r){ //注意传引用 
18     int temp = r.w;
19     r.w = r.h;
20     r.h = temp;
21 }
22 
23 void reverse(int x){
24     for(int i=0; i<3; i++){
25         if(x&1){
26             swap(rec[index[i]]);
27         }
28         x >>= 1;
29     }
30 }
31 
32 
33 bool judge(){    
34     int ans = false;
35     
36     if(rec[index[0]].w == rec[index[1]].w 
37         && rec[index[1]].w == rec[index[2]].w )
38         ans = true;
39     else if(rec[index[1]].w == rec[index[2]].w 
40         && rec[index[0]].h == rec[index[1]].h + rec[index[2]].h) 
41         ans = true;
42         
43     return ans;
44 }
45 
46 int main()
47 {
48     scanf("%d", &n);
49     while(n--){
50         for(int i=0; i<4; i++){
51             scanf("%d%d", &rec[i].w, &rec[i].h);
52             index[i] = i;
53         }
54         int flag = 0;
55         do{
56             for(int i=0; i<8; i++){
57                 reverse(i);
58                 if(judge()){
59                     flag = 1;
60                     break;
61                 }
62                 reverse(i);    
63             }
64             if(flag) break;
65         }while(next_permutation(index, index+4));
66         printf("%s\n", flag ? "Yes" : "No");
67     }
68     return 0;
69 }

 

目录
相关文章
|
1月前
|
Java Spring
使用枚举定义常量更好点儿
使用枚举定义常量更好点儿
14 1
|
1月前
|
安全 算法 编译器
【C++基础语法 枚举】C/C++ 中enum枚举量的介绍:介绍enum枚举量在C/C中的作用和使用方法
【C++基础语法 枚举】C/C++ 中enum枚举量的介绍:介绍enum枚举量在C/C中的作用和使用方法
32 2
|
11天前
|
算法
枚举算法的介绍
枚举算法的介绍
17 0
|
7月前
巧用枚举替代if
巧用枚举替代if
|
8月前
|
存储 算法 编译器
【C++技能树】令常规运算符用在类上 --类的六个成员函数II
C++中为了增强代码的可读性,加入了运算符的重载,与其他函数重载一样
37 0
|
10月前
|
缓存 算法 编译器
【C#本质论 十】合式类型(一)重写Object成员及操作符重载(上)
【C#本质论 十】合式类型(一)重写Object成员及操作符重载(上)
45 0
|
10月前
|
缓存 算法 C#
【C#本质论 十】合式类型(一)重写Object成员及操作符重载(下)
【C#本质论 十】合式类型(一)重写Object成员及操作符重载(下)
75 0
C语言——enum枚举实例、知识点。使用枚举,减少相同定义步骤,简洁数据1.1.5
枚举是C语言常见的一种基本数据类型,它可以避免多个整数定义的麻烦,使代码整洁干净易读如此一看,就觉得繁琐无比,大量重复#define xx明显增加代码量,且数值需自己一一对应而枚举,可以解决这种定义连续数值的过程当变量第一个值未自定义时,第一个枚举成员的默认值则为整型0,后续成员值依次加1,如此时MON=0,TUE=1,WED=2·····.........
C语言——enum枚举实例、知识点。使用枚举,减少相同定义步骤,简洁数据1.1.5
|
开发者
枚举(枚举中定义其它结构)|学习笔记
快速学习 枚举(枚举中定义其它结构)
|
Java 开发者
枚举(enum 类)|学习笔记
快速学习 枚举(enum 类)
135 0