2012-2013 ACM-ICPC East Central North America Regional Contest (ECNA 2012)
2015-05-21 10:32
756 查看
训练感想
从今天开始,HIT_Foodie队就进入了系统训练的阶段,也开始为上海大都会站的比赛开始做准备了。队里三个人,我最弱! 所以以后我一定会好好训练,争取不拖两位大爷的后腿!
今天的题难度就是regional难度,训练的时候因为一个
浮点误差的问题调试了很长时间。所以接下来总结一番,并且补上没做的题。
题目分析
先把题目放出来,然后是Gym地址。A题 Babs’ Box Boutique
题意
给n(n<10)个长方体,把这些长方体按照顺序叠放起来,注意叠放的时候,接触面要严格保持小于关系,(x <= a && y <= b) || (x <= b && y <= a)
直接搜索即可,tomriddly同学貌似忘了回溯,WA了一发。
/* written by tomriddly */ #include <bits/stdc++.h> using namespace std; int n; struct Box { int b[3]; inline void get() { scanf("%d%d%d", b + 0, b + 1, b + 2); } }a[11]; int ans = 0; bool vis[11]; inline bool check(const int &x, const int &y, const int &a, const int &b) { return (x <= a && y <= b) || (x <= b && y <= a); } inline void dfs(const Box &last, const int &x, const int &y, const int &depth) { if (ans < depth) ans = depth; for (int i = 1; i <= n; i++) if (!vis[i]) { vis[i] = true; if (check(a[i].b[0], a[i].b[1], last.b[x], last.b[y])) dfs(a[i], 0, 1, depth + 1); if (check(a[i].b[0], a[i].b[2], last.b[x], last.b[y])) dfs(a[i], 0, 2, depth + 1); if (check(a[i].b[2], a[i].b[1], last.b[x], last.b[y])) dfs(a[i], 2, 1, depth + 1); vis[i] = false; } } int main() { int cas = 0; while (~scanf("%d", &n) && n) { ans = 0; memset(vis, false, sizeof(vis)); for (int i = 1; i <= n; i++) a[i].get(); for (int i = 1; i <= n; i++) { vis[i] = true; dfs(a[i], 0, 1, 1); dfs(a[i], 0, 2, 1); dfs(a[i], 2, 1, 1); vis[i] = false; } printf("Case %d: %d\n", ++cas, ans); } return 0; }
B题 Flash Mob
题意
给一些点的坐标,求出到这些点的曼哈顿距离之和最小,且横竖坐标均最小的点的坐标及他们的曼哈顿距离之和
把给的x坐标排序,y坐标排序,各自选取中位数即可。注意
偶数个的时候选取n/2的值
/* written by jiefangxuanyan */ #include <cstdio> #include <algorithm> const int N=1100; int xs ,ys ; int main(){ int cn=0; while(true){ int n; scanf("%d",&n); if(!n){ return 0; } for(int i=0;i<n;i++){ scanf("%d%d",xs+i,ys+i); } std::sort(xs,xs+n); std::sort(ys,ys+n); int xm=xs[(n-1)/2],ym=ys[(n-1)/2]; int s=0; for(int i=0;i<n;i++){ s+=std::abs(xs[i]-xm); } for(int i=0;i<n;i++){ s+=std::abs(ys[i]-ym); } printf("Case %d: (%d,%d) %d\n",++cn,xm,ym,s); } }
C题 Hexagon Perplexagon
题意
这题有点恶心,题意就不解释了,算是一个搜索。我们直接用
next_permutation()居然 TLE 了
然后安神展开了一番剪枝,终于过了。
#include <cstdio> #include <algorithm> int in[10][10]; void rotate(int *h,int tgt,int pos){ for(int i=0;i<6;i++){ if(h[i]==tgt){ int tmp[10]; for(int j=0;j<6;j++){ tmp[(pos+j)%6]=h[(i+j)%6]; } for(int j=0;j<6;j++){ h[j]=tmp[j]; } return; } } } /*bool validate(const int *put){ rotate(in[put[0]],1,0); for(int i=0;i<6;i++){ rotate(in[put[i+1]],in[put[0]][i],(i+3)%6); } for(int i=0;i<6;i++){ if(in[put[i+1]][(i+2)%6]!=in[put[(i+1)%6+1]][(i+5)%6]){ return false; } } return true; }*/ bool dfs(int *perm,int pos){ if(pos==1){ rotate(in[perm[0]],1,0); } else if(pos>1){ rotate(in[perm[pos-1]],in[perm[0]][pos-2],(pos+1)%6); if(pos>2&&in[perm[pos-1]][(pos+2)%6]!=in[perm[pos-2]][(pos+5)%6]){ return false; } } if(pos==7){ return in[perm[1]][4]==in[perm[6]][1]; } for(int i=pos;i<7;i++){ std::swap(perm[pos],perm[i]); if(dfs(perm,pos+1)){ return true; } } for(int i=pos;i+1<7;i++){ std::swap(perm[i],perm[i+1]); } return false; } int main(){ int cn; scanf("%d",&cn); for(int ci=1;ci<=cn;ci++){ for(int i=0;i<7;i++){ for(int j=0;j<6;j++){ scanf("%d",in[i]+j); } } int perm[10]/*={3,0,5,6,1,4,2}*/; for(int i=0;i<7;i++){ perm[i]=i; } printf("Case %d:",ci); /*do{ if(validate(perm)){ goto lblSucc; } } while(std::next_permutation(perm,perm+7));*/ if(dfs(perm,0)){ for(int i=0;i<7;i++){ printf(" %d",perm[i]); } putchar('\n'); } else{ puts(" No solution"); } } return 0; }
D题 I’ve Got Your Back(gammon)
题意
给一个六位的序列,要求各位之和加起来是15。这样的序列一共有15504个。
把这些序列按照字典序排序,给定两种查询。1是查询第几个序列是什么,2是查询某个序列的序号是多少。
直接生成所有的序列,用map映射一下就可以了。
/* written by tomriddly */ #include <bits/stdc++.h> using namespace std; struct Fuck { int a[7]; inline friend bool operator <(const Fuck &x, const Fuck &y) { for (int i = 1; i <= 6; i++) if (x.a[i] != y.a[i]) return x.a[i] < y.a[i]; return false; } inline friend bool operator ==(const Fuck &x, const Fuck &y) { for (int i = 1; i <= 6; i++) if (x.a[i] != y.a[i]) return false; return true; } }a[15555]; int tmp[7], cnt = 0, n; char cmd[11]; map<Fuck, int> r; inline void dfs(int depth, int presum) { if (depth == 6) { int sum = 0; for (int i = 1; i <= 6; i++) sum += tmp[i]; if (sum == 15) { for (int i = 1; i <= 6; i++) a[cnt].a[i] = tmp[i]; cnt++; } return ; } for (int i = 0; i <= 15 - presum; i++) { tmp[depth + 1] = i; dfs(depth + 1, presum + i); } } int main() { int cas = 0; dfs(0, 0); //cout << cnt << endl; sort(a, a + cnt); /* for (int i = 0; i < cnt; i++) { for (int j = 1; j <= 6; j++) { printf("%d%c", a[i].a[j], j == 6 ? '\n' : ' '); } system("pause"); } */ for (int i = 0; i < cnt; i++) r[a[i]] = i; while (~scanf("%s", cmd) && cmd[0] != 'e') { if (cmd[0] == 'm') { for (int i = 1; i <= 6; i++) scanf("%d", &a[15550].a[i]); printf("Case %d: %d\n", ++cas, r[a[15550]]); } else { int x; scanf("%d", &x); printf("Case %d:", ++cas); for (int i = 1; i <= 6; i++) printf(" %d", a[x].a[i]); putchar('\n'); } } return 0; }
E题 Parencedence!
占坑,会了在写。应该是个对抗搜索,代码没时间写了。
F题 Road Series
先占着坑,等我看明白了再写。。。/* written by jiefangxuanyan */ #include <cstdio> #include <cstring> #include <algorithm> const int LEN=1100,MAXN=100000000; char in[LEN]; int storage[LEN*10]; bool has[MAXN]; int main(){ int cn; scanf("%d",&cn); for(int ci=1;ci<=cn;ci++){ int n,w; scanf("%d%d ",&n,&w); int pos=1; memset(has,0,sizeof(has)); has[0]=true; int maxSeen=0; for(int i=0;i<n;i++){ gets(in); int cnt=0; for(char *p=in;*p;p++){ int cur=0,i=0; while(true){ storage[cnt++]=cur; if(cur<MAXN&&'0'<=p[i]&&p[i]<='9'){ cur=cur*10+p[i]-'0'; i++; } else{ break; } } } std::sort(storage,storage+cnt); for(int i=0;i<cnt;i++){ if(storage[i]<pos+w){ maxSeen=std::max(storage[i],maxSeen); has[storage[i]]=true; while(has[pos]){ pos++; } } } } printf("Case %d: %d %d\n",ci,pos-1,maxSeen); } return 0; }
G题 Show Me the Money
题意
着重讲一下这道题。我们一上来就用了分数类,希望能够避免坑爹的浮点数误差。但是没有想到,使用long long竟然爆了。。。
没有办法,我们改成
double,但是还是WA了。经过一番思想斗争,我们决定把代码改成java高精度!可惜的是,这回不是WA了,而是 TLE。。。
挣扎了许久,这道题我们差不多纠结了两个小时。最后还是没招,看了题解。
又TM是
ceil()的时候加干扰。。。实在是太鬼畜了。。。
/* written by tomriddly */ #include <bits/stdc++.h> using namespace std; inline long long gcd(const long long &x, const long long &y) { return !y ? x : gcd(y, x % y); } /* struct Fenshu { long long fenzi, fenmu; inline Fenshu() {} inline Fenshu(const long long &fenzi, const long long &fenmu):fenzi(fenzi), fenmu(fenmu) {} inline friend bool operator <(const Fenshu &x, const Fenshu &y) { long long tongfen = gcd(x.fenmu, y.fenmu); return x.fenzi * (x.fenmu / tongfen) < y.fenzi * (y.fenmu / tongfen); } inline friend Fenshu operator *(const Fenshu &x, const Fenshu &y) { long long fenzi = x.fenzi * y.fenzi, fenmu = x.fenmu * y.fenmu, tongfen = gcd(fenzi, fenmu); return Fenshu(fenzi / tongfen, fenmu / tongfen); } }*/ typedef long double Fenshu; long double f[11][11]; map<string, int> num; int n; int main() { ios::sync_with_stdio(false); int cas = 0; while (cin >> n && n) { num.clear(); int n1, n2; string name1, name2; int cnt = 0; memset(f, 0, sizeof(f)); for (int i = 1; i <= n; i++) { cin >> n1 >> name1 >> name2 >> n2 >> name2; if (num.find(name1) == num.end()) num[name1] = ++cnt; if (num.find(name2) == num.end()) num[name2] = ++cnt; int u = num[name1], v = num[name2]; Fenshu v1 = (long double)n2 / n1, v2 = (long double)n1 / n2; if (f[u][v] <= 1e-14 || v1 < f[u][v]) f[u][v] = v1; if (f[v][u] <= 1e-14 || v2 < f[v][u]) f[v][u] = v2; } //cout << cnt << endl; int need; string needname; for (int k = 1; k <= cnt; k++) for (int i = 1; i <= cnt; i++) for (int j = 1; j <= cnt; j++) { if (f[i][k] <= 1e-14 || f[k][j] <= 1e-14) continue; Fenshu tmp = f[i][k] * f[k][j]; if (f[i][j] <= 1e-14 || tmp < f[i][j]) f[i][j] = tmp; //cout << tmp << endl; } cin >> need >> needname; int t = num[needname]; double ans = DBL_MAX; int ansi; long long fff; for (int i = 1; i <= cnt; i++) if (i != t && f[i][t] >= 1e-14) { long long tmp = (long long)ceill((long double)need / f[i][t] - 1e-8); if (tmp > 100000) continue; double kui = fabs((long double)tmp / f[t][i] - need); //cout << tmp << " " << i << ' ' << kui << endl; if (ans > kui) ans = kui, ansi = i, fff = tmp; } cout << "Case " << (++cas) << ": "; for (map<string, int>::iterator p = num.begin(); p != num.end(); p++) if (p->second == ansi) { cout << fff << " " << p->first << endl; break; } } } /* 4 23 a = 17 b 16 c = 29 e 5 b = 14 e 1 d = 7 f 100 a */
H题 Sofa, So Good
会了再补上。。I题 Town Square
题意
只看懂了题意。。给四个圆,半径都是5。。求一个最小的正方形,与他们四个圆都相切。。还不会,等会了再来补上。
相关文章推荐
- 2005-2006 ACM-ICPC East Central North America Regional Contest (ECNA 2005) H.Two Ends
- 2005-2006 ACM-ICPC East Central North America Regional Contest (ECNA 2005) G.Swamp Things
- 2005-2006 ACM-ICPC East Central North America Regional Contest (ECNA 2005) F.Square Count
- 2014-2015 ACM-ICPC East Central North America Regional Contest (ECNA 2014)
- 2012-2013 ACM-ICPC, NEERC, Central Subregional Contest H Milestones1 (暴力)
- 2012-2013 ACM-ICPC, NEERC, Central Subregional Contest
- 2016-2017 ACM-ICPC East Central North America Regional Contest (ECNA 2016) F 区间dp
- 2012-2013 ACM-ICPC Northeastern European Regional Contest (NEERC 12)
- [2012-2013ACM-ICPC,NEERC,Western Subregional Contest]Pattern Matching/[JZOJ3427]归途与征程
- 2012-2013 ACM-ICPC, Asia Tokyo Regional Contest Beautiful Spacing 二分 + dp + 双指针扫描
- Gym 101196 (East Central North America Regional Contest 2016)
- ACM ICPC East Central North America 1994_Simply Syntax
- 2012-2013 ACM-ICPC, Asia Tokyo Regional Contest F.Never Wait for Weights(带权并查集模板)
- 2012-2013 ACM-ICPC, NEERC, Moscow Subregional Contest
- 2013-2014 ACM ICPC Central European Regional Contest (CERC 13) K题(dp)
- 2013-2014 ACM ICPC Central European Regional Contest (CERC 13) I题Crane
- 2013-2014 ACM ICPC Central European Regional Contest (CERC 13) B题What does the fox say?
- 2013-2014 ACM-ICPC Brazil Subregional Programming Contest
- 2016-2017 ACM-ICPC, NEERC, Central Subregional Contest
- 2013-2014 ACM-ICPC, NEERC, Southern Subregional Contest(2013区域赛练习)