【HDOJ】1362 The Bermuda Triangle

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

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

3. 代码

  1 /* 1362 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <bitset>
 12 #include <algorithm>
 13 #include <cstdio>
 14 #include <cmath>
 15 #include <ctime>
 16 #include <cstring>
 17 #include <climits>
 18 #include <cctype>
 19 #include <cassert>
 20 #include <functional>
 21 #include <iterator>
 22 #include <iomanip>
 23 using namespace std;
 24 //#pragma comment(linker,"/STACK:102400000,1024000")
 25
 26 #define sti                set<int>
 27 #define stpii            set<pair<int, int> >
 28 #define mpii            map<int,int>
 29 #define vi                vector<int>
 30 #define pii                pair<int,int>
 31 #define vpii            vector<pair<int,int> >
 32 #define rep(i, a, n)     for (int i=a;i<n;++i)
 33 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 34 #define clr                clear
 35 #define pb                 push_back
 36 #define mp                 make_pair
 37 #define fir                first
 38 #define sec                second
 39 #define all(x)             (x).begin(),(x).end()
 40 #define SZ(x)             ((int)(x).size())
 41 #define lson            l, mid, rt<<1
 42 #define rson            mid+1, r, rt<<1|1
 43
 44 const int maxn = 30;
 45 const int maxm = 60;
 46 int c[maxn], s[maxn];
 47 int a[maxn], R[maxm];
 48 bool visit[maxm][maxm];
 49 int n, m, bound;
 50 bool flag;
 51
 52 void init() {
 53     rep(i, 1, maxn)
 54         c[i] = c[i-1] + i*2-1;
 55     rep(i, 1, maxn)
 56         s[i] = 6 * c[i];
 57 }
 58
 59 inline bool judge(int x, int y) {
 60     return y<=0 || y>bound || x<=0 || x>R[y];
 61 }
 62
 63 bool check(int x, int y, int n) {
 64     if (x & 1) {
 65         // straight triangle
 66         int yy = y;
 67         rep(i, 1, n+1) {
 68             int xx = x, l = i*2-1;
 69             rep(j, 0, l) {
 70                 if (judge(xx, yy) || visit[yy][xx])    return false;
 71                 ++xx;
 72             }
 73             ++yy;
 74         }
 75     } else {
 76         // reverse triangle
 77         int yy = y;
 78         int c = 0;
 79         per(i, 1, n+1) {
 80             int xx = x + c * 2, l = i*2-1;
 81             rep(j, 0, l) {
 82                 if (judge(xx, yy) || visit[yy][xx])    return false;
 83                 ++xx;
 84             }
 85             ++c;
 86             ++yy;
 87         }
 88     }
 89     return true;
 90 }
 91
 92 void update(int x, int y, int n, bool delta) {
 93     if (x & 1) {
 94         // straight triangle
 95         int yy = y;
 96         rep(i, 1, n+1) {
 97             int xx = x, l = i*2-1;
 98             rep(j, 0, l) {
 99                 visit[yy][xx] = delta;
100                 ++xx;
101             }
102             ++yy;
103         }
104     } else {
105         // reverse triangle
106         int yy = y;
107         int c = 0;
108         per(i, 1, n+1) {
109             int xx = x + c * 2, l = i*2-1;
110             rep(j, 0, l) {
111                 visit[yy][xx] = delta;
112                 ++xx;
113             }
114             ++c;
115             ++yy;
116         }
117     }
118 }
119
120 void dfs(int r, int dep) {
121     if (dep > bound)    {
122         flag = true;
123         return ;
124     }
125
126     int rr = r + 1, depp = dep;
127     if (r == R[dep]) {
128         rr = 1;
129         ++depp;
130     }
131
132     if (visit[dep][r])    {
133         dfs(rr, depp);
134     } else {
135         rep(i, 0, m) {
136             int l = a[i];
137             if (check(r, dep, l)) {
138                 update(r, dep, l, true);
139                 dfs(rr, depp);
140                 update(r, dep, l, false);
141                 if (flag)    return;
142             } else {
143                 break;
144             }
145         }
146     }
147 }
148
149 bool judge1() {
150     flag = false;
151     bound = n;
152     memset(visit, false, sizeof(visit));
153     rep(i, 1, n+1)
154         R[i] = 2*i-1;
155     dfs(1, 1);
156     return flag;
157 }
158
159 bool judge2() {
160     flag = false;
161     bound = n;
162     memset(visit, false, sizeof(visit));
163     rep(i, 1, n+1)
164         R[i] = 2*i-1;
165     dfs(1, 1);
166     return flag;
167 }
168
169 bool judge3() {
170     flag = false;
171     bound = n*2;
172     memset(visit, false, sizeof(visit));
173     rep(i, 1, n+1) {
174         R[i] = n*2 + 2*i-1;
175     }
176     rep(i, n+1, n*2+1) {
177         rep(j, 1, 2*(i-n))
178             visit[i][j] = true;
179         R[i] = (n + n)*2;
180     }
181     dfs(1, 1);
182     return flag;
183 }
184
185 void solve() {
186     sort(a, a+m);
187     rep(i, 0, m) {
188         if (n%a[i] == 0) {
189             puts("YES");
190             return ;
191         }
192     }
193     if (a[0] > n) {
194         puts("NO");
195         return ;
196     }
197
198     {    // filter unnecessary
199         int j = 1;
200
201         rep(i, 1, m) {
202             if (a[i] > n)
203                 break;
204             bool flag = true;
205             rep(k, 0, j) {
206                 if (a[i]%a[k] == 0) {
207                     flag = false;
208                 }
209             }
210             if (flag)
211                 a[j++] = a[i];
212         }
213         m = j;
214     }
215
216     if (judge1()) {
217         puts("YES");
218         return ;
219     }
220
221     if (judge2()) {
222         puts("YES");
223         return ;
224     }
225
226     if (judge3()) {
227         puts("YES");
228         return ;
229     }
230
231     puts("NO");
232 }
233
234 int main() {
235     cin.tie(0);
236     ios::sync_with_stdio(false);
237     #ifndef ONLINE_JUDGE
238         freopen("data.in", "r", stdin);
239         freopen("data.out", "w", stdout);
240     #endif
241
242     int t;
243
244     scanf("%d", &t);
245     while (t--) {
246         scanf("%d%d", &n,&m);
247         rep(i, 0, m)
248             scanf("%d", a+i);
249         solve();
250     }
251
252     #ifndef ONLINE_JUDGE
253         printf("time = %ldms.\n", clock());
254     #endif
255
256     return 0;
257 }
时间: 2024-10-09 13:17:12

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

【HDOJ】4956 Poor Hanamichi

基本数学题一道,看错位数,当成大数减做了,而且还把方向看反了.所求为最接近l的值. 1 #include <cstdio> 2 3 int f(__int64 x) { 4 int i, sum; 5 6 i = sum = 0; 7 while (x) { 8 if (i & 1) 9 sum -= x%10; 10 else 11 sum += x%10; 12 ++i; 13 x/=10; 14 } 15 return sum; 16 } 17 18 int main() { 1

【HDOJ】1099 Lottery

题意超难懂,实则一道概率论的题目.求P(n).P(n) = n*(1+1/2+1/3+1/4+...+1/n).结果如果可以除尽则表示为整数,否则表示为假分数. 1 #include <cstdio> 2 #include <cstring> 3 4 #define MAXN 25 5 6 __int64 buf[MAXN]; 7 8 __int64 gcd(__int64 a, __int64 b) { 9 if (b == 0) return a; 10 else return

【HDOJ】2844 Coins

完全背包. 1 #include <stdio.h> 2 #include <string.h> 3 4 int a[105], c[105]; 5 int n, m; 6 int dp[100005]; 7 8 int mymax(int a, int b) { 9 return a>b ? a:b; 10 } 11 12 void CompletePack(int c) { 13 int i; 14 15 for (i=c; i<=m; ++i) 16 dp[i]

【HDOJ】3509 Buge&#39;s Fibonacci Number Problem

快速矩阵幂,系数矩阵由多个二项分布组成.第1列是(0,(a+b)^k)第2列是(0,(a+b)^(k-1),0)第3列是(0,(a+b)^(k-2),0,0)以此类推. 1 /* 3509 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #incl

【HDOJ】1818 It&#39;s not a Bug, It&#39;s a Feature!

状态压缩+优先级bfs. 1 /* 1818 */ 2 #include <iostream> 3 #include <queue> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <algorithm> 8 using namespace std; 9 10 #define MAXM 105 11 12 typedef struct {

【HDOJ】2424 Gary&#39;s Calculator

大数乘法加法,直接java A了. 1 import java.util.Scanner; 2 import java.math.BigInteger; 3 4 public class Main { 5 public static void main(String[] args) { 6 Scanner cin = new Scanner(System.in); 7 int n; 8 int i, j, k, tmp; 9 int top; 10 boolean flag; 11 int t

【HDOJ】2425 Hiking Trip

优先级队列+BFS. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 #define MAXN 25 8 9 typedef struct node_st { 10 int x, y, t; 11 node_st() {} 12 node_st(int xx, int yy, int tt)

【HDOJ】1686 Oulipo

kmp算法. 1 #include <cstdio> 2 #include <cstring> 3 4 char src[10005], des[1000005]; 5 int next[10005], total; 6 7 void kmp(char des[], char src[]){ 8 int ld = strlen(des); 9 int ls = strlen(src); 10 int i, j; 11 12 total = i = j = 0; 13 while (

【HDOJ】2795 Billboard

线段树.注意h范围(小于等于n). 1 #include <stdio.h> 2 #include <string.h> 3 4 #define MAXN 200005 5 #define lson l, mid, rt<<1 6 #define rson mid+1, r, rt<<1|1 7 #define mymax(x, y) (x>y) ? x:y 8 9 int nums[MAXN<<2]; 10 int h, w; 11 12