【multimap/pair/数组】#28 A. Bender Problem
来源:互联网 发布:大连弘历软件 编辑:程序博客网 时间:2024/04/27 22:12
看到一道好长的题我主要是比较懒的看题,就去cf上想找到题意,然后——
然后我就看到了这么些看起来好吓人的解题报告:
A. Bender Problem
Solution by Polichka
Let's look at the first nail. If it is occupied by the fold place, then Bender will put next fold place on the third nail, then on fifth and so on. Else, is the first nail occupied by end, than second, fourth, sixth and so on nail will be occupied by the fold places.
Let's see, if we can complete our polyline with the first nail, occupied by rhe fold place. It means we should check, if we have an unused pod with length dist(nails[n], nails[1]) + dist(nails[1], nails[2]). Then check the third nail and so on.
If we have completed the polyline, then we have an answer. Else repeat previous procedure, but starting from the second nail
А. Задача Бендера.
Будем говорить, что мы крепим j-ый прут к i-ому гвоздю, если мы крепим j-ый прут местом сгиба к i -ому гвоздю.
Для начала поймем, что если мы прикрепляем прут к первому гвоздю, то остальные прутья мы сможем прикреплять только к третьему, пятому и т.д. Соответственно, если мы крепим прут ко второму гвоздю, то все остальные прутья мы можем крепить к четвертому, шестому и т.д. То есть либо мы крепим все прутья к гвоздям с четным номером, либо все к гвоздям с нечетным.
Если задача имеет решение, то нам надо выбрать к каким по четности гвоздям мы будем крепить прутья, а также поднабор из n / 2 прутьев, который и будет считаться ответом.
Если мы крепим j-ый прут к i-ому гвоздю, то len[j] = dist(i, i - 1) + dist(i, i + 1), где len[j] - длина j-ого прута, а dist(i, k) - расстояние между гвоздями с номерами i и k.
Ограничения задачи позволяли решать ее за O(nm). Проходим внешним циклом по гвоздям, к которым будут крепиться пруты(сначала по гвоздям с четными номерами, потом по гвоздям с нечетными номерами), проходим внутренним циклом по прутьям и проверяем: можем ли мы прикрепить хотя бы один из оставшихся прутьев к текущему гвоздю. Если можем, то помечаем этот прут и далее его не рассматриваем, если нет, то проделываем то же самое для гвоздей с нечетными номерами, но при этом нужно снять все пометки с прутьев, сделанные при рассмотрении гвоздей с четными номерами. Если же и для нечетного случая мы не нашли ответ, то искомого поднабора не существует.
这道题我个人嗯理解的意思是有这么多个钉子,相邻的俩一定是水平或者竖直的,有这么多线要做个框把它框起来,每根线可以折着用,问咋框。
My Source Code: 30ms AC 0k length:1578 B
#include <cmath> #include <vector>#include <cctype>#include <cstdio>#include <string>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define Max(a,b) ((a)>(b)?(a):(b))#define Min(a,b) ((a)<(b)?(a):(b))struct point{int x;int y;}a[505];//listintn=0,m=0;int len[505];intans[505];intmrk[505];void print(){puts("YES");for ( int i=1; i<=n; i++ )printf("%d ",(ans[i]) ? ans[i] : -1);}bool judge(int i, int j){return len[j] == ( abs(a[i-1].x - a[i].x) + abs(a[i-1].y - a[i].y) ) + ( abs(a[i+1].x - a[i].x) + ( abs(a[i+1].y - a[i].y ) ) ) ;//绳长是否与两个钉子间距相等 }int main(){memset(len,0,sizeof(len));memset(ans,0,sizeof(ans));memset(mrk,0,sizeof(mrk));cin>>n>>m;for(int i=1;i<=n;i++)cin>>a[i].x>>a[i].y;for(int j=1;j<=m;j++)cin>>len[j];//consider about the head and taila[0].x = a[n].x;a[0].y = a[n].y;a[n+1].x = a[1].x;a[n+1].y = a[1].y;//start from 1st or 2ndint type = 1 ,flag = 0, t = 0;for(int i=type;i<=n;i+=2){flag = 0;for (int j=1; j<=m; j++) if (!mrk[j] && judge(i,j)) {flag = 1;ans[i] = j;mrk[j] = 1;break; }if ( flag == 0 ) { t = 1; break; }}if ( !t ) print();else{type++;memset(ans,0,sizeof(ans));memset(mrk,0,sizeof(mrk));for(int i=type;i<=n;i+=2){flag = 0;for (int j=1; j<=m; j++) if (!mrk[j] && judge(i,j)) {flag = 1;ans[i] = j;mrk[j] = 1;break; }if ( flag == 0 ) { puts("NO");return 0;}}print();}return 0;}
备看——
C++:
【multimap】解法 From:watashi@cf
#include <map>#include <cstdio>#include <algorithm>using namespace std;int main() {int n, m, t, x[1024], y[1024];multimap<int, int> r, rr;multimap<int, int>::iterator it;scanf("%d%d", &n, &m);for (int i = 1; i <= n; ++i) {scanf("%d%d", &x[i], &y[i]);}x[0] = x[n];y[0] = y[n];x[n + 1] = x[1];y[n + 1] = y[1];for (int i = 0; i <= n; ++i) {x[i] = abs(x[i + 1] - x[i]) + abs(y[i + 1] - y[i]);}for (int i = 1; i <= m; ++i) {scanf("%d", &t);rr.insert(make_pair(t, i));}for (int s = 1; s <= 2; ++s) {bool flag = true;r = rr;y[s - 1] = -1;for (int i = s; i <= n; i += 2) {it = r.find(x[i - 1] + x[i]);if (it == r.end()) {flag = false;break;}y[i] = it->second;y[i + 1] = -1;r.erase(it);}if (flag) {puts("YES");for (int i = 1; i <= n; ++i) {printf("%d ", y[i]);}return 0;}}puts("NO");return 0;}
C++: 【pair】
From:zeonsgtr@cf
#include <cstdio>#include <algorithm>#include <cstring>#include <cstdlib>#include <iostream>#include <cassert>#include <sstream>#include <numeric>#include <climits>#include <string>#include <cctype>#include <ctime>#include <cmath>#include <vector>#include <queue>#include <list>#include <map>#include <set>using namespace std;#define x first#define y secondtypedef pair<int, int> Point;const int N = 555;int n, m;int len[N];int ans[N];bool visited[N];Point a[N];int dist(const Point &a, const Point &b, const Point &c) {return abs(a.x - b.x) + abs(a.y - b.y) + abs(b.x - c.x) + abs(b.y - c.y);}bool check(bool flag) {memset(visited, 0, sizeof(visited));memset(ans, -1, sizeof(ans));for (int i = flag; i < n; i += 2) {int need = dist(a[(i - 1 + n) % n], a[i], a[(i + 1) % n]);flag = false;for (int j = 0; j < m; ++j)if (!visited[j] && len[j] == need) {flag = true;visited[j] = true;ans[i] = j + 1;break;}if (!flag)return false;}return true;}int main() {scanf("%d%d", &n, &m);for (int i = 0; i < n; ++i)scanf("%d%d", &a[i].x, &a[i].y);for (int i = 0; i < m; ++i)scanf("%d", len + i);if (check(0) || check(1)) {puts("YES");for (int i = 0; i < n; ++i)printf("%d%c", ans[i], i < n - 1 ? ' ' : '\n');} else {puts("NO");}}
C++:
15ms 0k完美解法 From:Choojae@cf
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <string>#include <cctype>#include <algorithm>#define maxn 505using namespace std;int n,m,l[maxn],x[maxn],y[maxn],ans[maxn];bool flag[maxn];void init() { scanf("%d%d",&n,&m); int i; for (i=0;i<n;i++)scanf("%d%d",&x[i],&y[i]); for (i=1;i<=m;i++)scanf("%d",&l[i]); } void work() { int i,st,j,k; for (st=0;st<=1;st++) { memset(ans,-1,n*4); memset(flag+1,false,m*sizeof(bool)); for (i=st;i<n;i+=2) { k=abs(x[i]-x[(i+n-1)%n])+abs(y[i]-y[(i+n-1)%n])+abs(x[(i+1)%n]-x[i])+abs(y[(i+1)%n]-y[i]); for (j=1;j<=m;j++)if (l[j]==k && !flag[j]){flag[j]=true;ans[i]=j;break;} if (ans[i]==-1)break; } if (i>=n) { puts("YES"); for (i=0;i<n-1;i++)printf("%d ",ans[i]);printf("%d\n",ans[n-1]); return; } } puts("NO"); } int main() { init(); work(); return 0; }
Python解法:
R=lambda:map(int,raw_input().split())n,m=R()a=map(lambda x:complex(*x),(R() for _ in xrange(n)))b=R()def nail(i): c={} for u,x in enumerate(b):c[x]=c.get(x,[])+[u+1] t=[-1]*n for u in xrange(0,n,2): w=int(abs(a[i]-a[i-1])+abs(a[(i+1)%n]-a[i])+0.5) if c.get(w): t[i]=c[w].pop() else: return 0 i+=2 return 'YES\n'+' '.join(map(str,t))print nail(0) or nail(1) or 'NO'
- 【multimap/pair/数组】#28 A. Bender Problem
- pair map multimap说明
- BNU Problem A Best Matched Pair
- map(multimap)与pair
- UVa11507 - Bender B. Rodríguez Problem
- pair、map、set、multiset、multimap用法简介
- Problem 1001 Duplicate Pair
- uva10245The Closest Pair Problem
- Problem 1001 Duplicate Pair
- Problem 1001Duplicate Pair
- UVa 11507 - Bender B. Rodríguez Problem
- set/multiset,map/multimap的使用与比较+pair介绍
- 关联容器(map、set、multimap、multiset、pair、unordered_map)
- 10245 - The Closest Pair Problem
- 10245 - The Closest Pair Problem
- UVaOJ10245 - The Closest Pair Problem
- Uva10245-The Closest Pair Problem
- UVA10245 - The Closest Pair Problem
- C#获取Word文档结构图 并且转成Datatable表格
- python import与from...import....的区别
- 关于JS中的constructor与prototype
- String和StringBuilder的简单对比
- C++11 function使用
- 【multimap/pair/数组】#28 A. Bender Problem
- 新加坡公民与国人结婚的比例呈增长趋势
- 类的加载顺序
- flex的渲染两种用法
- Machine Learning Done Wrong(机器学习七种易犯的错误)
- eclipse的问题帖子
- HTTPS的压力测试工具 -- httperf
- 第七周作业--背包问题
- 【口腔上火怎么办,食疗法】