PROB Packing Rectangles [ANALYSIS]----第一题是3天前看到的,事隔一课考试,全校答辩,今天终于A出来了,每天都在想,都在想,终于对这个题目比较明白了。
/* solution 1 1 枚举排列数 2 枚举翻转 3 按6种情况枚举最小的 4 所有情况记录所有最小值 */ int rectx[4],recty[4]; int meijux[4],meijuy[4]; bool vis[4]; int sumx,sumy,sumarea = INT_MAX; map<PII,int> vec; map<PII,int>::iterator p; void update(int x,int y) { if(sumarea > x * y) { sumarea = x * y; vec.clear(); vec[make_pair(min(x,y),max(x,y))] = 1; } else if(sumarea == x * y) { vec[make_pair(min(x,y),max(x,y))] = 1; } } int maxb(int a=0,int b=0,int c=0,int d=0) { return max(a,max(b,max(c,d))); } // 判断函数 void check() { // case 1 // 0 1 2 3 sumx = meijux[0] + meijux[1] + meijux[2] + meijux[3]; sumy = maxb(meijuy[0],meijuy[1],meijuy[2],meijuy[3]); update(sumx, sumy); // case 2 // 0 1 2 // 3 sumx = maxb(meijux[0] + meijux[1] + meijux[2],meijux[3]); sumy = meijuy[3] + maxb(meijuy[1],meijuy[2],meijuy[0]); update(sumx,sumy); // case 3 // 0 1 2 // 3 2 sumx = meijux[2] + maxb(meijux[0] + meijux[1],meijux[3]); sumy = maxb(meijuy[3] + maxb(meijuy[0],meijuy[1]),meijuy[2]); update(sumx,sumy); // case 4 // 0 1 3 // 2 sumx = maxb(meijux[1],meijux[2]) + meijux[0] + meijux[3]; sumy = maxb(meijuy[1] + meijuy[2],meijuy[0],meijuy[3]); update(sumx,sumy); // case 5 // case 6 // 0 1 // 2 3 sumy = maxb(meijuy[0] + meijuy[2],meijuy[1] + meijuy[3]); if(meijuy[2] >= meijuy[3]) { if(meijuy[2] >= meijuy[3] + meijuy[1]) { sumx = maxb(maxb(meijux[1],meijux[3]) + meijux[2],meijux[0]); } else { sumx = maxb(meijux[2] + meijux[1],meijux[2] + meijux[3],meijux[0] + meijux[1]); } } else { if(meijuy[3] >= meijuy[0] + meijuy[2]) { sumx = maxb(maxb(meijux[0],meijux[2]) + meijux[3],meijux[1]); } else { sumx = maxb(meijux[2] + meijux[3],meijux[0] + meijux[3] ,meijux[0] + meijux[1]); } } //DB(sumx<<" "<<sumy); update(sumx,sumy); } void dfs(int depth) { if(depth == 4) { check(); return; } // 全排列枚举 F(i,4){ if(!vis[i]) { //DB(i); vis[i] = 1; // 横竖枚举 F(j,2) { if(j == 0) { meijux[depth] = rectx[i]; meijuy[depth] = recty[i]; } else { meijux[depth] = recty[i]; meijuy[depth] = rectx[i]; } dfs(depth + 1); } vis[i] = 0; } } return; } int main() { FOPENTI FOPENTO F(i,4) SCFD(rectx[i],recty[i]); SET(vis,0); dfs(0); PCFLN(sumarea); for(p = vec.begin();p != vec.end();p++){ printf("%d %d\n",p->first.first,p->first.second); } }
我这里用map判断重复的,然后对应题目的6个情况,事实证明不考虑第5种情况也行,和第四种重复,第6种要分开情况考虑,每个人分类不同,但是肯定是安装 2 号与 3 号木块的高度进行分类的(其实第6中和前面还是有重复的)case 1 ~ 5在题目上面很清楚,就不说了只说case 6.
高度很容易计算:
sumy = maxb(meijuy[0] + meijuy[2],meijuy[1] + meijuy[3]); // sumx 安装下面进行分类,只是sumx 取那两个木块的最大值有所变化 if(meijuy[2] >= meijuy[3]) { if(meijuy[2] >= meijuy[3] + meijuy[1]) { sumx = maxb(maxb(meijux[1],meijux[3]) + meijux[2],meijux[0]); } else { sumx = maxb(meijux[2] + meijux[1],meijux[2] + meijux[3],meijux[0] + meijux[1]); } } else { if(meijuy[3] >= meijuy[0] + meijuy[2]) { sumx = maxb(maxb(meijux[0],meijux[2]) + meijux[3],meijux[1]); } else { sumx = maxb(meijux[2] + meijux[3],meijux[0] + meijux[3] ,meijux[0] + meijux[1]); } }这次把AC的case贴出来。以后用。。题目debug了两次,第一次是手贱,‘,’ 打错 ‘+’,结果maxb是带默认参数的,没报错,WA。。第二次是情况6考虑错了,重新考虑,A了!
USER: Rain M [m3324631] TASK: packrec LANG: C++ Compiling... Compile: OK Executing... Test 1: TEST OK [0.000 secs, 3188 KB] Test 2: TEST OK [0.000 secs, 3188 KB] Test 3: TEST OK [0.000 secs, 3188 KB] Test 4: TEST OK [0.000 secs, 3188 KB] Test 5: TEST OK [0.000 secs, 3188 KB] Test 6: TEST OK [0.000 secs, 3188 KB] Test 7: TEST OK [0.000 secs, 3188 KB] Test 8: TEST OK [0.000 secs, 3188 KB] Test 9: TEST OK [0.000 secs, 3188 KB] Test 10: TEST OK [0.000 secs, 3188 KB] Test 11: TEST OK [0.000 secs, 3188 KB] Test 12: TEST OK [0.000 secs, 3188 KB] Test 13: TEST OK [0.000 secs, 3188 KB] Test 14: TEST OK [0.000 secs, 3188 KB] Test 15: TEST OK [0.000 secs, 3188 KB] Test 16: TEST OK [0.000 secs, 3188 KB] Test 17: TEST OK [0.000 secs, 3188 KB] Test 18: TEST OK [0.000 secs, 3188 KB] Test 19: TEST OK [0.000 secs, 3188 KB] Test 20: TEST OK [0.000 secs, 3188 KB] Test 21: TEST OK [0.000 secs, 3188 KB] All tests OK. Your program ('packrec') produced all correct answers! This is your submission #4 for this problem. Congratulations! Here are the test data inputs: ------- test 1 ---- 1 2 2 3 3 4 4 5 ------- test 2 ---- 20 20 20 20 20 20 20 20 ------- test 3 ---- 4 5 5 4 4 5 16 1 ------- test 4 ---- 4 5 2 5 5 2 2 10 ------- test 5 ---- 12 18 4 6 2 17 19 3 ------- test 6 ---- 10 10 5 5 15 15 20 20 ------- test 7 ---- 1 1 1 20 1 20 20 20 ------- test 8 ---- 5 8 3 12 15 4 14 10 ------- test 9 ---- 4 5 5 6 6 4 4 5 ------- test 10 ---- 1 5 5 10 10 15 15 20 ------- test 11 ---- 3 4 8 5 7 1 4 5 ------- test 12 ---- 17 11 16 20 4 6 13 19 ------- test 13 ---- 4 2 2 6 2 3 5 8 ------- test 14 ---- 1 2 2 3 3 4 4 5 ------- test 15 ---- 4 8 8 12 12 16 16 20 ------- test 16 ---- 3 5 1 3 2 4 2 5 ------- test 17 ---- 4 3 4 4 6 3 5 5 ------- test 18 ---- 49 50 49 50 49 50 49 50 ------- test 19 ---- 10 50 45 30 28 38 36 20 ------- test 20 ---- 50 49 49 48 48 47 47 46 ------- test 21 ---- 50 49 48 47 46 45 45 44 Keep up the good work! Thanks for your submission!
PROB The Clocks [ANALYSIS] ---- 这个题目也是够纠结的。
前期一直出现这个 RE
bad syscall #32000175 (RT_SIGPROCMASK)
Your program printed data to stderr. Here is the data: ------------------- terminate_called_after_throwing_an_instance_of_'std::bad_alloc' __what():__std::bad_alloc -------------------
没办法,各种百度 google,终于有点头绪了,STL 的堆栈或者指针溢出或者出错了,但是和 stderr 有什么关系?求大牛各种解释!
// solution 1: BFS, // 总共9种方法,不会全用,每个点最多4种状态,一共 4^9 种状态 /* solution 1 data base: node status hash with (3 * 3 to int ) { 9 9 12 3 6 9 12 6 6 6 1 2 3 4 6 3 6 trans -> 334 222 212(int) 9 ways : 11011,111,110110,1001001,10111010,100100100,011011000,111000000,110110000 } 1 input 2 search: for 9 - hash - expend(); 3 output; */ struct node { int step,way,pre; int mat; node(int a=0,int b=0,int c=0,int p=0): step(a),mat(b),way(c),pre(p){} }first,nodetop,nodetmp; hash_map<int,bool> has; node que[MAXN]; int front =0,rear=0,kk=0,anss[100]; int expe[] = {0,110110000,111000000,11011000,100100100,10111010,1001001,110110,111,11011}; int hashi(int a[]) { int n=0; F(i,9) { switch(a[i]){ case 3: n = n*10 + 1;break; case 6: n = n*10 + 2;break; case 9: n = n*10 + 3;break; case 12: n = n*10 + 4;break; } } return n; } int expend(int hx,int cas) { int matt = hx + expe[cas],ans=0; int fuck[9]={0},i=0,matm = matt; while(matm) { fuck[i++] = matm%10; if(fuck[i-1] == 5) fuck[i-1]=1; matm /= 10; } ans += fuck[i-1]; for(int j = i-2;j>=0;j--) { ans *= 10; ans += fuck[j]; } return ans; } int bfs() { /* init: hash表 队列 取队头 - expend - hash判重 - 压入队列 */ has.clear(); //que.push_back(first);rear++; que[rear++] = first; while(front != rear) { nodetop = que[front++]; if(nodetop.mat == 444444444) return nodetop.step; nodetmp.step = nodetop.step + 1; nodetmp.pre = front-1; //expend() FOR(i,1,9) { nodetmp.mat = expend(nodetop.mat,i); nodetmp.way = i; if(has.find(nodetmp.mat) == has.end()) { has[nodetmp.mat] = 1; //que.push_back(nodetmp);rear++; que[rear++] = nodetmp; } } } return 0; } void output(int depth) { if(que[depth].pre != 0) { output(que[depth].pre); } anss[kk++] = que[depth].way; return ; } int main() { FOPENTI FOPENTO kk=0; int a[9]; F(i,9) SCF(a[i]); first=node(0,hashi(a),0,0); int de = bfs(); if(de) { output(front-1); for(int i = 0;i<kk-1;i++){ printf("%d ",anss[i]); } printf("%d\n",anss[kk-1]); } }
不得不说,这个题目数据要求挺严格的,。
自勉一下
USER: Rain M [m3324631] TASK: clocks LANG: C++ Compiling... Compile: OK Executing... Test 1: TEST OK [0.011 secs, 7876 KB] Test 2: TEST OK [0.011 secs, 7876 KB] Test 3: TEST OK [0.097 secs, 8608 KB] Test 4: TEST OK [0.162 secs, 9268 KB] Test 5: TEST OK [0.184 secs, 9532 KB] Test 6: TEST OK [0.475 secs, 11644 KB] Test 7: TEST OK [0.508 secs, 11908 KB] Test 8: TEST OK [0.529 secs, 11908 KB] Test 9: TEST OK [0.508 secs, 11908 KB] All tests OK. Your program ('clocks') produced all correct answers! This is your submission #10 for this problem. Congratulations! Here are the test data inputs: ------- test 1 ---- 9 9 12 6 6 6 6 3 6 ------- test 2 ---- 12 9 12 9 9 9 12 9 12 ------- test 3 ---- 6 9 3 3 3 9 12 12 12 ------- test 4 ---- 9 3 9 9 9 9 9 9 9 ------- test 5 ---- 6 12 12 12 12 12 12 12 12 ------- test 6 ---- 3 12 9 6 6 6 12 12 12 ------- test 7 ---- 12 3 3 3 6 6 12 3 6 ------- test 8 ---- 12 3 9 9 12 12 3 6 9 ------- test 9 ---- 9 12 9 12 3 12 9 12 9 Keep up the good work! Thanks for your submission
突然发现,这个section前后居然不是同一天,时差。。。ORZ
PROB Arithmetic Progressions [ANALYSIS] ---- 这个题目很给力啊。
这个题目的关键就在定边界 和 倒着枚举等差的系数k
bool has[MAXN]; int n,m; int cal(int a,int b,int k) { return a + k * b; } int main() { FOPENTI FOPENTO //FOPEN SCFD(n,m); FOR(i,0,m) FOR(j,0,m) { has[i*i + j*j] = 1; } n--; bool flag = 1; int upsum = 2 * m * m; int upa = 2 * m * m - n + 1; int upb = 2 * m * m / n; FOR(b,1,upb) FOR(a,0,upa) { if( cal(a,b,n) > upsum) continue; bool isok = 1; for(int k = n;k >= 0;k--) { int ans = cal(a,b,k); if(!has[ans]){ isok = 0; break; } } if(isok) printf("%d %d\n",a,b),flag = 0; } if(flag) puts("NONE"); }
USER: Rain M [m3324631] TASK: ariprog LANG: C++ Compiling... Compile: OK Executing... Test 1: TEST OK [0.000 secs, 3340 KB] Test 2: TEST OK [0.000 secs, 3340 KB] Test 3: TEST OK [0.000 secs, 3340 KB] Test 4: TEST OK [0.000 secs, 3340 KB] Test 5: TEST OK [0.022 secs, 3340 KB] Test 6: TEST OK [0.130 secs, 3340 KB] Test 7: TEST OK [1.490 secs, 3340 KB] Test 8: TEST OK [3.380 secs, 3340 KB] Test 9: TEST OK [2.981 secs, 3340 KB] All tests OK. Your program ('ariprog') produced all correct answers! This is your submission #4 for this problem. Congratulations! Here are the test data inputs: ------- test 1 ---- 3 2 ------- test 2 ---- 5 7 ------- test 3 ---- 14 10 ------- test 4 ---- 10 13 ------- test 5 ---- 12 50 ------- test 6 ---- 18 100 ------- test 7 ---- 21 200 ------- test 8 ---- 22 250 ------- test 9 ---- 25 250 Keep up the good work! Thanks for your submission!
晚上想想怎么证明这个稀疏关系。
PROB Mother's Milk [ANALYSIS] ---- 模拟一下,一开始没想到怎么模拟,仔细读题,发现了。
还有一个地方,就当 A 是0的时候记录 C 的容量是多少!。
// solution 1 dfs // solution 2 DP maybe /* solution 1 1 select one ( no 0 ) 2 chose one to pull (if can't return) remeber all c */ map<int,int> mt; map<int,int>::iterator p; int has[22][22][22];//hash int a[3]; //init int tma[3]={0}; //statu void dfs() { for(int i = 0;i<3;i++){ if(tma[i]) { for(int j = 0;j<3;j++) { if(i == j) continue; if(a[j] - tma[j]) { int botm = min(tma[i],a[j] - tma[j]); tma[i] -= botm; tma[j] += botm; if(!has[tma[0]][tma[1]][tma[2]]) { if(!tma[0])mt[tma[2]]=1; has[tma[0]][tma[1]][tma[2]] = 1; dfs(); } tma[i] += botm; tma[j] -= botm; } } } } return; } int main() { FOPENTI FOPENTO SET(has,0);mt.clear(); SCFT(a[0],a[1],a[2]); tma[2]=a[2]; has[0][0][a[2]]=1;mt[a[2]]; dfs(); p = mt.begin(); printf("%d",p->first); p++; for(;p != mt.end();p++){ printf(" %d",p->first); } puts(""); }
我没有让0输出,WA了一次。。。悲剧,不然用能看见first time congratulation等等了。。
USER: Rain M [m3324631] TASK: milk3 LANG: C++ Compiling... Compile: OK Executing... Test 1: TEST OK [0.000 secs, 3224 KB] Test 2: TEST OK [0.000 secs, 3224 KB] Test 3: TEST OK [0.000 secs, 3224 KB] Test 4: TEST OK [0.000 secs, 3224 KB] Test 5: TEST OK [0.000 secs, 3224 KB] Test 6: TEST OK [0.000 secs, 3224 KB] Test 7: TEST OK [0.000 secs, 3224 KB] Test 8: TEST OK [0.000 secs, 3224 KB] Test 9: TEST OK [0.000 secs, 3224 KB] Test 10: TEST OK [0.000 secs, 3224 KB] All tests OK. Your program ('milk3') produced all correct answers! This is your submission #2 for this problem. Congratulations! Here are the test data inputs: ------- test 1 ---- 2 5 10 ------- test 2 ---- 20 20 20 ------- test 3 ---- 5 11 15 ------- test 4 ---- 2 12 20 ------- test 5 ---- 19 4 11 ------- test 6 ---- 5 11 13 ------- test 7 ---- 3 20 20 ------- test 8 ---- 7 16 20 ------- test 9 ---- 20 10 9 ------- test 10 ---- 7 12 18 Keep up the good work! Thanks for your submission!
1.4 小结
这一节还是有很多值得做的题目,大都以深搜为主,模拟,或者枚举。
可以见得,很多题目都能用DP来做,是在是太神了,等这个chapter完事了回头看看给类DP。