您的位置:首页 > 其它

2015 Asia - Jakarta D - An ICPC Problem without Statement

2016-01-24 22:56 375 查看

题目描述:

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=104601#problem/D

题解:

1.当一定大于等于0的时候,就是我们尽量凑2的时候,我们放2,-2,1, -1, 0的顺序,每次能放就放最多的,和-1的 dfs深搜.

2.当必须是-的时候,要么全部必须要选,要么全是负数(可以推一下) 所以就是绝对值小的.

重点:

1.负数的时候单拉出来绝对值最小.

2.减一的小方法

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

const int maxn = 1e5 + 100;
int n, A, B;
int a[maxn];
int ans[maxn], val, tag;
int b[20], number[10], have[20];
int num;
int change(int x) {
if(x == 2)
return 0;
if(x == -2)
return 1;
if(x == 1)
return 2;
if(x == -1)
return 3;
return 4;
}
void dfs(int pos, int now) {
if(pos == 4) {
if(now + have[number[pos]] < num)
return;
int t = num - now;
if(t == 0) {
int tval = b[0] + b[1];
int ttag = (b[1] + b[3]) % 2;
if(ttag == 1)
ttag = -1;
else
ttag = 1;
if(ttag > tag || (ttag == tag && (tag == 1 && tval > val || tag == -1 && tval < val)))
{
tag = ttag;
val = tval;
for(int i = 0; i <= 3; i++) {
ans[i] = b[i];
}
ans[4] = num - now;
}

}
else {
if(tag < 0) {
tag = 0;
val = 0;
for(int i = 0; i <= 3; i++) {
ans[i] = b[i];
}
ans[4] = num - now;
}
}
return;
}
int tmp = min(num - now, have[number[pos]]);
b[pos] = tmp;
dfs(pos + 1, now + tmp);
if(tmp > 0) {
b[pos] = tmp - 1;
dfs(pos + 1, now + tmp - 1);
}
}
vector<int> res;

void solve() {
tag = -2;
for(num = A; num <= B; num++)
dfs(0, 0);
/*printf("%d  %d\n", tag, val);
for(int i = 0; i <= 4; i++) {
printf("%d ", ans[i]);
}*/
res.clear();
if(tag >= 0) {
;
}
else {
if(A == n && A == B) {
for(int i = 0; i <= 4; i++)
ans[i] = have[i];
}
else {
for(int i = 0; i <= 4; i++)
ans[i] = 0;
ans[3] = min(A, have[3]);
ans[1] = A - ans[3];
}
}
for(int i = 0; i < n; i++) {
if(ans[change(a[i])] > 0) {
res.push_back(i);
ans[change(a[i])]--;
}
}
printf("%d\n", res.size());
for(int i = 0; i < res.size(); i++) {
printf("%d%c", res[i] + 1, (i == res.size() - 1 ? '\n' : ' '));
}
}

int main() {
//freopen("d.txt", "r" ,stdin);
number[0] = 0;
number[1] = 1;
number[2] = 2;
number[3] = 3;
number[4] = 4;
int ncase;
scanf("%d", &ncase);
for(int _ = 1; _ <= ncase; _++) {
printf("Case #%d:\n", _);
scanf("%d %d %d", &n, &A, &B);
for(int i = 0; i <= 4; i++)
have[i] = 0;
for(int i = 0; i < n; i++) {
scanf("%d", &a[i]);
have[change(a[i])]++;
}
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: