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. JSP Workshop

    http://www.cnblogs.com/ITtangtang/p/4126395.html 发现http://www.tutorialspoint.com/里的资料很全也很不错啊! 资料:htt ...

  2. 1-Highcharts 3D图之普通3D柱状图与带空值

    <!DOCTYPE> <html lang='en'> <head> <title>1-Highcharts 3D图之普通3D柱状图与带空值</t ...

  3. vs2008 添加与修改模板.

    添加 我的模板: 路径:  C:\Users\Administrator\Documents\Visual Studio 2008\Templates\ItemTemplates\Visual C# ...

  4. HDU1013Digital Roots

    G - Digital Roots Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u   ...

  5. Tomcat漏洞说明与安全加固

    Tomcat是Apache软件基金会的一个免费的.开放源码的WEB应用服务器,可以运行在Linux和Windows等多个平台上,由于其性能稳定.扩展性好.免费等特点深受广大用户的喜爱.目前,互联网上绝 ...

  6. Eclipse 字体选择

    Windows下推荐使用Consolas Linux下推荐使用DejaVu Sans Mono, Website: http://dejavu-fonts.org/wiki/Main_PageDown ...

  7. 使用MbrFix.exe修复MBR分区表

    在卸载linux Ubuntu之前,先修复MBR,然后再删除Linux分区就可以了.而MbrFix.exe 就是这样一个Windows 修复MBR的应用程序软件,MbrFix.exe 不仅支持Wind ...

  8. [转载] Linux下多路复用IO接口 epoll select poll 的区别

    原地址:http://bbs.linuxpk.com/thread-43628-1-1.html 废话不多说,一下是本人学习nginx 的时候总结的一些资料,比较乱,但看完后细细揣摩一下应该就弄明白区 ...

  9. MongoDB (八) MongoDB 文档操作

    一. MongoDB 插入文档 insert() 方法 要插入数据到 MongoDB 集合,需要使用 MongoDB 的  insert() 或 save() 方法. 语法 insert() 命令的基 ...

  10. sublime3可用key

    —– BEGIN LICENSE —–Nicolas HennionSingle User LicenseEA7E-8660758A01AA83 1D668D24 4484AEBC 3B04512C8 ...