1. 题目描述
给定几个三角形拼成一个百慕大三角形。

2. 基本思路
基本思路肯定是搜索,关键点是剪枝。
(1) 若存在长度为$l$的边,则一定可以拼成长度为$k \cdot l$的三角形,则可拼成长度为$k \cdot l$的百慕大三角形;
(2) 长度超过百慕大三角形的边长的三角形没有任何价值;
(3) 百慕大三角形中每个正三角形可以作为正多边形的顶点,倒三角形可以作为倒正三角形的顶点。
因此,可以将每个三角形映射到二维坐标,高度为$y$,倒三角形的$x$坐标为偶数,正三角形的$x$坐标为奇数。
对于每个有效的坐标,枚举可以使用的三角形。暴力深搜可解。
然后,观察可发现每个百慕大是由6个正三角形或3个平行四边形组成。因此,假设可以拼成三角形或平行四边形,那么一定可以拼成百慕大。
对于不同的形状,不需要重写dfs函数,只需要限定好边界即可。

3. 代码

 /* 1362 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <bitset>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 const int maxn = ;
const int maxm = ;
int c[maxn], s[maxn];
int a[maxn], R[maxm];
bool visit[maxm][maxm];
int n, m, bound;
bool flag; void init() {
rep(i, , maxn)
c[i] = c[i-] + i*-;
rep(i, , maxn)
s[i] = * c[i];
} inline bool judge(int x, int y) {
return y<= || y>bound || x<= || x>R[y];
} bool check(int x, int y, int n) {
if (x & ) {
// straight triangle
int yy = y;
rep(i, , n+) {
int xx = x, l = i*-;
rep(j, , l) {
if (judge(xx, yy) || visit[yy][xx]) return false;
++xx;
}
++yy;
}
} else {
// reverse triangle
int yy = y;
int c = ;
per(i, , n+) {
int xx = x + c * , l = i*-;
rep(j, , l) {
if (judge(xx, yy) || visit[yy][xx]) return false;
++xx;
}
++c;
++yy;
}
}
return true;
} void update(int x, int y, int n, bool delta) {
if (x & ) {
// straight triangle
int yy = y;
rep(i, , n+) {
int xx = x, l = i*-;
rep(j, , l) {
visit[yy][xx] = delta;
++xx;
}
++yy;
}
} else {
// reverse triangle
int yy = y;
int c = ;
per(i, , n+) {
int xx = x + c * , l = i*-;
rep(j, , l) {
visit[yy][xx] = delta;
++xx;
}
++c;
++yy;
}
}
} void dfs(int r, int dep) {
if (dep > bound) {
flag = true;
return ;
} int rr = r + , depp = dep;
if (r == R[dep]) {
rr = ;
++depp;
} if (visit[dep][r]) {
dfs(rr, depp);
} else {
rep(i, , m) {
int l = a[i];
if (check(r, dep, l)) {
update(r, dep, l, true);
dfs(rr, depp);
update(r, dep, l, false);
if (flag) return;
} else {
break;
}
}
}
} bool judge1() {
flag = false;
bound = n;
memset(visit, false, sizeof(visit));
rep(i, , n+)
R[i] = *i-;
dfs(, );
return flag;
} bool judge2() {
flag = false;
bound = n;
memset(visit, false, sizeof(visit));
rep(i, , n+)
R[i] = *i-;
dfs(, );
return flag;
} bool judge3() {
flag = false;
bound = n*;
memset(visit, false, sizeof(visit));
rep(i, , n+) {
R[i] = n* + *i-;
}
rep(i, n+, n*+) {
rep(j, , *(i-n))
visit[i][j] = true;
R[i] = (n + n)*;
}
dfs(, );
return flag;
} void solve() {
sort(a, a+m);
rep(i, , m) {
if (n%a[i] == ) {
puts("YES");
return ;
}
}
if (a[] > n) {
puts("NO");
return ;
} { // filter unnecessary
int j = ; rep(i, , m) {
if (a[i] > n)
break;
bool flag = true;
rep(k, , j) {
if (a[i]%a[k] == ) {
flag = false;
}
}
if (flag)
a[j++] = a[i];
}
m = j;
} if (judge1()) {
puts("YES");
return ;
} if (judge2()) {
puts("YES");
return ;
} if (judge3()) {
puts("YES");
return ;
} puts("NO");
} int main() {
cin.tie();
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif int t; scanf("%d", &t);
while (t--) {
scanf("%d%d", &n,&m);
rep(i, , m)
scanf("%d", a+i);
solve();
} #ifndef ONLINE_JUDGE
printf("time = %ldms.\n", clock());
#endif return ;
}

【HDOJ】1362 The Bermuda Triangle的更多相关文章

  1. 【Leetcode】Pascal&#39;s Triangle II

    Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3, Return [1,3 ...

  2. 【BZOJ】1914: [Usaco2010 OPen]Triangle Counting 数三角形

    [题意]给定坐标系上n个点,求能构成的包含原点的三角形个数,n<=10^5. [算法]极角排序 [题解]补集思想,三角形个数为C(n,3)-不含原点三角形. 将所有点极角排序. 对于一个点和原点 ...

  3. 【HDOJ】4729 An Easy Problem for Elfness

    其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...

  4. 【HDOJ】【3506】Monkey Party

    DP/四边形不等式 裸题环形石子合并…… 拆环为链即可 //HDOJ 3506 #include<cmath> #include<vector> #include<cst ...

  5. 【HDOJ】【3516】Tree Construction

    DP/四边形不等式 这题跟石子合并有点像…… dp[i][j]为将第 i 个点开始的 j 个点合并的最小代价. 易知有 dp[i][j]=min{dp[i][j] , dp[i][k-i+1]+dp[ ...

  6. 【HDOJ】【3480】Division

    DP/四边形不等式 要求将一个可重集S分成M个子集,求子集的极差的平方和最小是多少…… 首先我们先将这N个数排序,容易想到每个自己都对应着这个有序数组中的一段……而不会是互相穿插着= =因为交换一下明 ...

  7. 【HDOJ】【2829】Lawrence

    DP/四边形不等式 做过POJ 1739 邮局那道题后就很容易写出动规方程: dp[i][j]=min{dp[i-1][k]+w[k+1][j]}(表示前 j 个点分成 i 块的最小代价) $w(l, ...

  8. 【HDOJ】【3415】Max Sum of Max-K-sub-sequence

    DP/单调队列优化 呃……环形链求最大k子段和. 首先拆环为链求前缀和…… 然后单调队列吧<_<,裸题没啥好说的…… WA:为毛手写队列就会挂,必须用STL的deque?(写挂自己弱……s ...

  9. 【HDOJ】【3530】Subsequence

    DP/单调队列优化 题解:http://www.cnblogs.com/yymore/archive/2011/06/22/2087553.html 引用: 首先我们要明确几件事情 1.假设我们现在知 ...

随机推荐

  1. 【BZOJ】【2480】【SPOJ 3105】Mod

    扩展BSGS Orz zyf……然而他的题解对AC大神的题解作了引用……而坑爹的百度云……呵呵了... 扩展BSGS模板题 /************************************* ...

  2. nsight 使用问题

    slot 0 offset 0 stride DXGI_FORMAT_r32b32g32_FLOAT 这样一个memory 100.0000, 100.0000,10.0000,1.0000 stri ...

  3. websphere变成英文了

    ebsphere页面怎么变成中文? 浏览器 -- internet选项 --  常规 -- "语言" -- 打开后: 1. 如果只有"英语(美国)[en-US]" ...

  4. MYSQL导入导出.sql文件(转)

    一.MYSQL的命令行模式的设置: 桌面->我的电脑->属性->环境变量->新建-> PATH=“:path\mysql\bin;”其中path为MYSQL的安装路径. ...

  5. 企业级账号更新app

    企业级账号 版本更新总结       参考:http://jingyan.baidu.com/article/a3aad71aa5fbfbb1fb0096b1.html 1.打包ipa,plist工具 ...

  6. WinInet:HTTPS 请求出现无效的证书颁发机构的处理

    首先,微软提供的WinInet库封装了对网页访问的方法. 最近工作需要从https服务器获取数据,都知道https和http网页的访问方式不同,多了一道证书认证程序,这样就使得https在请求起来比h ...

  7. javascript实现数据结构与算法系列:队列 -- 链队列和循环队列实现及示例

    1 队列的基本概念 队列(Queue):也是运算受限的线性表.是一种先进先出(First In First Out ,简称FIFO)的线性表.只允许在表的一端进行插入,而在另一端进行删除. 队首(fr ...

  8. uva 11324

    Problem B: The Largest Clique Given a directed graph G, consider the following transformation. First ...

  9. 即时通讯UI-聊天界面(UITableView显示左右两人聊天)

    目录 1.创建UITableView对象并设置相关属性 2.创建cellModel模型 //枚举类型 typedef enum { ChatMessageFrom = ,//来自对方的消息 ChatM ...

  10. Nutch配置:nutch-default.xml详解

    /×××××××××××××××××××××××××××××××××××××××××/ Author:xxx0624 HomePage:http://www.cnblogs.com/xxx0624/ ...