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。

浙公网安备 33010602011771号