题目:http://acm.hdu.edu.cn/showproblem.php?pid=4665
题目大意:两个相同的序列搞在一起,给你他们搞起来的总的序列,每个元素最多只可能重复出现4次,现在要把他们两个拆开,问你一种可行方案,分别用0、1标记。
思路:比赛的时候一直想不出它这个4到底有什么用处,又想不出什么好的解法,听到别人说暴力可以过,我们也直接上暴力了,最后30分钟开始敲,还剩最后10分钟的时候A的。。 = =
看了题解,居然是2-sat,但是回头一想,感觉这个建图有点略复杂,因为有两种情况,先留个坑,以后再来填吧。。
先上个暴搜代码吧,代码如下:
#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
const int MAXN = 2222 ;
map<int ,int > m;
int a[MAXN];
int num[MAXN];
int a1[MAXN],a2[MAXN];
int len;
int ok;
int ans[MAXN];
void dfs(int n,int pos1,int pos2)
{
if(pos1>len/2||pos2>len/2) return ;
//printf("n = %d,pos1 = %d,pos2 = %d\n",n,pos1,pos2);
if(ok) return ;
if(pos1==len/2&&pos2==len/2)
{
for(int i = 1;i<=pos2;i++)
ans[a2[i]] = 1;
ok =1;
return ;
}
if(num[a[n]]==2)
{
if(ok) return ;
a1[pos1+1] = n;
num[a[n]]--;
dfs(n+1,pos1+1,pos2);
num[a[n]]++;
}
else if((pos1<pos2&&a[a2[pos1+1]]==a[n])||pos1>=pos2)
{
if(ok) return ;
a1[pos1+1] = n;
dfs(n+1,pos1+1,pos2);
}
if(num[a[n]]==1)
{
if(ok) return ;
a2[pos2+1] = n;
num[a[n]]--;
dfs(n+1,pos1,pos2+1);
num[a[n]]++;
}
else if((pos2<pos1&&a[a1[pos2+1]]==a[n])||pos2>=pos1)
{
if(ok) return ;
a2[pos2+1] = n;
dfs(n+1,pos1,pos2+1);
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
len = n;
m.clear();
int tot = 0;
for(int i = 1;i<=n;i++)
{
scanf("%d",&a[i]);
if(m.find(a[i])==m.end())
m[a[i]] = ++tot ;
}
memset(num,0,sizeof(num));
for(int i = 1;i<=n;i++)
{
a[i] = m[a[i]];
num[a[i]] ++ ;
}
memset(ans,0,sizeof(ans));
ok=0;
dfs(1,0,0);
for(int i = 1;i<=n;i++)
printf("%d",ans[i]);
puts("");
}
return 0;
}