输入:n (1<n<=27).
输出不同方案的个数.
注意:纯打表必和谐掉,不信就试试;有限打表,你懂的。
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int te[30][30]; //三角形
int record[30];
int n,sd,sum,ct; //第一行符号个数,总量半数,方案总数,+个数
inline void backtrack(int t)
{
if((ct>sd)||(t*(t-1)/2-ct>sd))
return;
else if(t>n) sum++;
else
{
for(int i=0;i<=1;i++) //子集树
{
te[1][t]=i;
ct += i;
register int ls=0;
for(int j=2;j<=t;j++)
{
te[j][t-j+1]=te[j-1][t-j+2]^te[j-1][t-j+1];
ls += te[j][t-j+1];
}
ct += ls;
backtrack(t+1);
ct -= ls; //去掉外侧列,回溯一层
ct -= i;
}
}
}
int main(){
record[27]=5804913;
record[24]=822229;
record[23]=431095;
//有限打表
while(scanf("%d",&n)!=EOF)
{
if(!record[n])
{
sd=n*(n+1)/2;
sum=0;
ct=0;
if(sd%2==1); //必没有答案
else
{
sd/=2;
backtrack(1);
}
record[n]=sum;
}
else
{
sum=record[n];
}
cout<<sum<<endl;
}
}