这道题题意有点难懂,其实问题可以转换为求区间是否相交,以及包含关系是否正确,没什么算法的东西,写程序的时候小心注意不要出现bug就行了,注意判断输入数据错误的条件还有配对不成功的情况,题目不难,就是要把代码调好有点消耗时间。
#include <stdio.h>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
#define MAX_SIZE 3000
typedef int START_POS;
typedef int INDEX;
map<START_POS,INDEX> m;
int v[MAX_SIZE*2];
struct node
{
int value;
int start;
int end;
};
struct node arr[MAX_SIZE];
int cmp(const void *a, const void *b)
{
struct node *pa = (struct node*)a;
struct node *pb = (struct node*)b;
return pa->start - pb->start;
}
void func(int len)
{
int i, j;
int count;
bool f1, f2, f3;
int start_pos;
int sum_value;
if(len%2)
{
printf(":-( Try again.\n");
return;
}
count = 0;
for(i=1; i<len; i++)
{
if(v[i] < 0)
{
for(j=i+1; j<=len; j++)
if(v[i] == -1*v[j])
{
arr[count].start = i;
arr[count].end = j;
arr[count].value = v[j];
count ++;
v[j] = 0;
break;
}
}
}
if(count != len/2)
{
printf(":-( Try again.\n");
return;
}
qsort((void*)arr, count, sizeof(struct node), cmp);
m.clear();
for(i=0; i<count; i++)
m[arr[i].start] = i;
//开始检查是否正确
for(i=0; i<count; i++)
{
f1 = f2 = f3 = true;
sum_value = 0;
for(j=i+1; j<count; )
{
if(arr[j].start > arr[i].end)
break;
//检查区间有没有交叉的情况出现
if(arr[j].end > arr[i].end)
{
f1 = false;
goto judge;
}
//检查包含的区间的权值是不是小于arr[i]的权值
if(arr[j].value >= arr[i].value)
{
f2 = false;
goto judge;
}
sum_value += arr[j].value;
start_pos = arr[j].end+1;
while(1)
{
if(start_pos >= arr[i].end)
{
j = count;
break;
}
if(m.find(start_pos) != m.end())
{
j = m[start_pos];
break;
}
start_pos ++;
}
}
if(sum_value >= arr[i].value)
{
f3 = false;
goto judge;
}
judge:
if(!f1 || !f2 || !f3)
{
printf(":-( Try again.\n");
return;
}
}
printf(":-) Matrioshka!\n");
}
int main(void)
{
int x, count;
int res;
char ch;
while(1)
{
count = 1;
while(1)
{
res = scanf("%d", &x);
if(res == EOF)
goto end;
v[count++] = x;
ch = getchar();
if(ch == '\n')
{
func(count-1);
break;
}
}
}
end:
return 0;
}