暴力破解# 系列文章目录
文章目录
A . Division
暴力跑模拟分母
#define inf 0x3f3f3f3f
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n=1;
while(scanf("%d",&n)!=EOF&&n)
{
int i,b,c=1233;
int flag=1;
char x[99];
while(c++)
{
b=c*n;
sprintf(x,"%05d%05d",b,c);
if(strlen(x)>10) break;
int s[12];
memset(s,0,sizeof(s));
for(i=0;i<10;i++)
{
if(s[x[i]-'0']!=0) break;
else s[x[i]-'0']++;
}
if(i==10) {printf("%05d / %05d = %d\n",b,c,n); flag=0;}
}
if(flag) printf("There are no solutions for %d.\n",n);
printf("\n");
}
return 0;
}
}
B . Maximum Product
纯暴力跑,
我三个循环一点也没优化…
#include<bits/stdc++.h>
using namespace std;
int a[30];
typedef long long ll
int main()
{
int n,kss= 1;
while(cin>>n){
long long maxx = 1,m = -123456;
memset(a,0,sizeof(a));
for(int i = 0;i < n;i++)
cin>>a[i];
for(int i = 0;i < n;i++){
for(int j = i;j < n;j++){
for(int k = i;k <= j;k++){
maxx *= a[k];
}
if(maxx > m) m = maxx;
maxx = 1;
}
}
cout<<"Case #"<<kss++<<": The maximum product is ";
if(m <= 0) cout<<0<<"."<<endl;
else
cout<<m<<"."<<endl;
cout<<endl;
}
return 0;
}
C . Fractions Again?!
最难的就是找到模拟的范围
因为两个数相等时取最大值
所以(1/k)=(2/y)所以
从k+1模拟到2k
x=(yk)/(y-k)
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+5;
int a[maxn];
int b[maxn];
int main()
{
int n,i,x,num;
while(cin>>n)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
num=0;
for(i=n+1; i<=n*2; i++)
{
if(n*i%(i-n))
continue;
x=n*i/(i-n);
a[num]=x;
b[num]=i;
num++;
}
printf("%d\n",num);
for(i=0; i<num; i++)
printf("1/%d = 1/%d + 1/%d\n",n,a[i],b[i]);
}
return 0;
}
D . Prime Ring Problem
DFS
跑到(第一个数和第二个数(最大的)和是素数为止)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int s[maxn];
ll n;
int a[20],vis[20];
bool su(int n)
{
if(n<2)return false;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
{
return false;
}
}
return true;
}
void dfs(int x)
{
if(x==n&&su(a[1]+a[n]))//终止条件
{
for(int i=1;i<n;i++)
{
printf("%d ",a[i]);
}
printf("%d\n",a[n]);
}
else
{
for(int i=2;i<=n;i++)
{
if(!vis[i]&&su(i+a[x]))
{
a[x+1]=i;
vis[i]=1;
dfs(x+1);
vis[i]=0;
}
}
}
}
int main()
{
int flag=0;
while(scanf("%d",&n)!=EOF)
{
memset(vis,0,sizeof(vis));
a[1]=1;
if(flag)
cout<<endl;
flag++;
printf("Case %d:\n",flag);
dfs(1);
}
return 0;
}
E . Krypton Factor
dfs
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+5;
int n, l;
int a[maxn];
bool f(int x)//判断是不是困难串
{
if(x == 1)
return 1;
bool flag;
for(int i=1;i<=x/2;i++)
{
flag=1;
for(int j=x-2*i;j<x-i; j++)
if(a[j] != a[j + i])
flag = 0;
if(flag)
return 0;
}
return 1;
}
void dfs(int x)
{
if(n == 0)
{
for(int i = 0; i<x; i += 4)
{
if(i != 0 && i % (64) == 0)
cout<<endl;
else if(i)
cout << " ";
for(int j = 0; j < 4 && i + j < x; j++)
putchar('A' + a[i + j]);
}
cout<<endl;
cout <<x<<endl;
}
for(int i=0;i<l&&n; i++)
{
a[x] =i;
if(f(x+1))//递归条件
{
n--;
dfs(x + 1);
}
}
}
int main()
{
while(cin >> n >> l)
{
memset(a, -1, sizeof(a));
if(n==0&&l==0)
{
return 0;
}
dfs(0);
}
return 0;
}
F . Bandwidth
这是一个图,输入给出的是某个节点。冒号后面的是和这个节点相邻的节点有哪些 分号代表一个描述结束;
每一种排法中,相邻点距离最大的,作为这种排法的带宽。 问哪种排法带宽最小;
求最小宽度 用全排列即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
vector<int> v[26];
bool ch[26];
int ans[10],id[10];
int main(){
string line;
while(cin>>line && line[0]!='#'){
for(int i=0;i<26;i++) v[i].clear();
memset(ch,0,sizeof(ch));
for(int i=0,j,len=line.length();i<len;i++){
ch[line[i]-'A']=true;
for(j=i+2;j<len && line[j]!=';';j++){
v[line[i]-'A'].push_back(line[j]-'A');
ch[line[j]-'A']=true;
}
i=j;
}
int n=0;
for(int i=0;i<26;i++) if(ch[i]) id[n++]=i;
int res=n;
do{
int maxn=0;
for(int i=0;i<n;i++){
for(int j=0,len=v[id[i]].size();j<len;j++){
for(int k=0;k<n;k++){
if(id[k]==v[id[i]][j]) {
maxn=max(maxn,abs(k-i));
break;
}
}
if(maxn>=res) break;
}
if(maxn>=res) break;
}
if(res>maxn){
memcpy(ans,id,sizeof(id));
res=maxn;
}
}while(next_permutation(id,id+n));
for(int i=0;i<n;i++)
cout<<char(ans[i]+'A')<<" ";
cout<<"-> "<<res<<endl;
}
return 0;
}
————————————————
版权声明:本文为CSDN博主「牛郎恋刘娘,刘娘念牛郎」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_52172364/article/details/119033291
武子哥yyds
G . Mobile Computing
#include<bits/stdc++.h>
using namespace std;
struct Tree {
double L, R;
Tree():L(0),R(0) {}
}tree[1<<6];
int n, vis[1<<6];
double r, w[1<<6];
int cur;
double mmax;
void dfs(int d)
{
if(d==n-1){
if(tree[cur].L+tree[cur].R<=r){
mmax=max(mmax,tree[cur].L+tree[cur].R);
return;
}
}
for(int i=1;i<=cur;i++){
if(!vis[i]){
for(int j=1;j<=cur;j++){
if(!vis[j]&&i!=j){
vis[i]=vis[j]=1;
w[++cur]=w[i]+w[j];
int ll=w[i],rr=w[j];
double wl=rr*(1.0)/(ll+rr),wr=1-wl;
tree[cur].L=max(tree[i].L+wl,tree[j].L-wr);
tree[cur].R=max(tree[j].R+wr,tree[i].R-wl);
dfs(d+1);
vis[i]=vis[j]=vis[cur]=0;
tree[cur].L=tree[cur].R=0;
cur--;
}
}
}
}
}
int main()
{
int T;
cin>>T;
while(T--){
cur=0;
memset(tree,0,sizeof(tree));
memset(w,0,sizeof(w));
scanf("%lf%d",&r,&n);
for(int i=1;i<=n;i++){
scanf("%lf",&w[i]);
cur++;
}
mmax=-1;
memset(vis,0,sizeof(vis));
dfs(0);
if(mmax==-1)cout<<mmax<<endl;
else printf("%.16lf\n",mmax);
}
return 0;
}
H . Fill
武子哥yyds
T组测试数据,每组测试数据输入4个整数,分别表示第一个杯子的容量、第二个杯子的容量、第三个杯子的量、目标容量,4个整数(小于200大于0)。输出最小的总倒水量和目标容量,如果倒不出目标容量,就 输出能倒出的小于目标容量的最大的容量的总倒水量和容量。
a->b a->c b->a b->c c->a c->b 有这几种情况
桶是没有刻度的 只有容量大小
我们优先提取出 倒水过程中用量最少的 因为这样是最优的
#include<bits/stdc++.h>
#include<iostream>
#include<cstring>
#include<queue>
#define inf 0x3f3f3f3f
//2147483647
using namespace std;
typedef long long ll;
typedef pair<double, double> PII;
ll n,m,k;
ll cnt=0,sum=0;
ll mod=1e9+7;
const int maxn=1e6+199;
ll x,y;
int cap[3];
int vis[250][250];
int ans[250];
struct Node{
int v[3];
int dis;
bool operator <(const Node& res) const{
return res.dis<dis;
}
}f,t;
void __init__(const Node & u){
for(int i=0;i<3;i++){
int k=u.v[i];
if(ans[k]<0||ans[k]>u.dis) ans[k]=u.dis;
}
}
void bfs(int a,int b,int c,int d){
memset(vis,0,sizeof(vis));
memset(cap,0,sizeof(cap));
memset(ans,-1,sizeof(ans));
cap[0]=a;cap[1]=b;cap[2]=c; //桶的容量
priority_queue<Node>q;
f.v[0]=0;
f.v[1]=0;
f.v[2]=c;
f.dis=0;
vis[0][0]=1;
q.push(f);
while(q.size()){
f=q.top(); //提取出dis最小的 dis代表 倒水使用量
q.pop();
__init__(f);
if(ans[d]>=0) break; //如果这个水量已经达到 直接break;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(i==j) continue;
if(f.v[i]==0||f.v[j]==cap[j]) continue;
int tmp=min(cap[j],f.v[i]+f.v[j])-f.v[j]; //tmp 代表j桶可以接收多少体积
t=f;
t.v[i]=f.v[i]-tmp;
t.v[j]=f.v[j]+tmp;
t.dis=f.dis+tmp;
if(!vis[t.v[0]][t.v[1]]) //如果这个状态未曾有过 入队
{
vis[t.v[0]][t.v[1]]=1;
q.push(t);
}
}
}
}
while(d>=0){
if(ans[d]>=0) {
printf("%d %d\n",ans[d],d);
return;
}
d--;
}
}
int main(){
cin>>n;
while(n--){
int a,b,c,d;
cin>>a>>b>>c>>d;
bfs(a,b,c,d);
}
}
I . The Morning after Halloween
BFS,题目大意是让最多三个鬼回到一模一样的大写字母那,tnl
#incldue<bits/stdc++.h>
using namespace std;
int bfs();
bool conflict(int a, int b, int na, int nb);
int encoding(int a, int b, int c);
const int MAXN = 150;
const int MAXS = 20;
const int dx[] = { 1,-1,0,0,0 };
const int dy[] = { 0,0,1,-1,0 };
int s[3], t[3];//保存初末状态
int deg[MAXN], G[MAXN][5];//deg:某个格子有多少个相连的格子 ,G:存某个格子可以用到哪些格子
int d[MAXN][MAXN][MAXN]; //走到某个状态经过的步数
int main()
{
int w, h, n;
while (scanf("%d %d %d", &w, &h, &n) && n) {
getchar();
char maze[MAXS][MAXS];
for (int i = 0; i < h; i++)
fgets(maze[i], 20, stdin);//听说直接scanf会超时
//为之后转化为一维数组做准备
int cnt = 0, x[MAXN], y[MAXN], id[MAXN][MAXN];//cnt:非过道个数;x,y数组用来存储第cnt个过道的x,y值;
for (int i = 0; i < h; i++) { //id是来存储过道某个对应的cnt值
for (int j = 0; j < w; j++) {
if (maze[i][j] != '#') {
if (islower(maze[i][j]))
s[maze[i][j] - 'a'] = cnt;
if (isupper(maze[i][j]))
t[maze[i][j] - 'A'] = cnt;
x[cnt] = i; y[cnt] = j; id[i][j] = cnt++;
}
}
}
//初始化deg,G。deg:每个过道5个移动方式上与之相邻的过道个数
for (int i = 0; i < cnt; i++) {
deg[i] = 0;
for (int dir = 0; dir < 5; dir++) {
int newx = x[i] + dx[dir]; int newy = y[i] + dy[dir];
if (maze[newx][newy] != '#') G[i][deg[i]++] = id[newx][newy];
}
}
//如果鬼的个数不足3个,补成三个,方便在BFS中进行对每个鬼进行行动,从而不需要动态考虑
//并且在deg和G中开辟一个过道来存放该添加的鬼的始末位置。
if (n <= 2) {
deg[cnt] = 1; G[cnt][0] = cnt; s[2] = t[2] = cnt++;
}
if (n <= 1) {
deg[cnt] = 1; G[cnt][0] = cnt; s[1] = t[1] = cnt++;
}
printf("%d\n", bfs());
}
return 0;
}
int bfs()
{
queue<int> q;
memset(d, -1, sizeof(d));
d[s[0]][s[1]][s[2]] = 0;
q.push(encoding(s[0], s[1], s[2]));//进行编码,放进栈中
while (q.size()) {
int x = q.front(); q.pop();
int a = (x >> 16) & 0xff, b = (x >> 8) & 0xff, c = x & 0xff;//获取abc
if (a == t[0] && b == t[1] && c == t[2]) return d[a][b][c];//到达终点
for (int i = 0; i < deg[a]; i++) {//a能移动的位置
int na = G[a][i];
for (int j = 0; j < deg[b]; j++) {
int nb = G[b][j];
if (conflict(a, b, na, nb)) continue;//如果冲突:a,b移动到同一个位置 或者 a,b交换位置
for (int k = 0; k < deg[c]; k++) {
int nc = G[c][k];
if (conflict(a, c, na, nc))continue;
if (conflict(b, c, nb, nc))continue;
if (d[na][nb][nc] != -1)continue;//d有值说明该状态已经访问过
d[na][nb][nc] = d[a][b][c] + 1;
q.push(encoding(na, nb, nc));
}
}
}
}
}
bool conflict(int a, int b, int na, int nb)
{
return (na == nb) || (na == b && nb == a);
}
int encoding(int a, int b, int c)
{
return a << 16 | b << 8 | c;
}
J . Editing a Book
迭代加深法
题目大意:将一个数字序列以最少的剪切次数粘贴成另一个数字序列。
剪枝策略判断:当前估价函数值+当前深度>预先最大搜索深度 然后剪枝
剪枝最多改变三个数字位置的正确性
每次搜索前h>(maxd-d)*3时剪枝 (maxd-d)是剩余搜索次数
#include<bitsdc++.h>
using namespace std;
const int maxn = 9;
int n, a[maxn];
bool is_finish() {
for(int i = 0; i < n-1; i++)
if(a[i] >= a[i+1]) return false;
return true;
}// 判断是否到达目标状态
int h() {
int cnt = 0;
for(int i = 0; i <n-1; i++)
if(a[i]+1 != a[i+1]) cnt++;
if(a[n-1] != n) cnt++;
return cnt;
} //统计需要变更的总数
bool dfs(int d, int maxd) {
if(d*3 + h() > maxd*3) return false; //估价函数
if(is_finish()) return true; //边界条件
int b[maxn], former[maxn];
memcpy(former, a, sizeof(a)); //存放原图
for(int i = 0; i < n; i++)
for(int j = i; j < n; j++) {
int cnt = 0;
for(int k = 0; k < n; k++)
if(k < i || k > j) b[cnt++] = a[k];
for(int k = 0; k <= cnt; k++) {
int cnt2 = 0;
for(int p = 0; p < k; p++) a[cnt2++] = b[p]; //插入已经拍好序的
for(int p = i; p <= j; p++) a[cnt2++] = former[p]; //插入
for(int p = k; p < cnt; p++) a[cnt2++] = b[p]; //插入终止状态
if(dfs(d+1, maxd)) return true;
memcpy(a,former, sizeof(a));
}
}
return false;
}
int solve() {
if(is_finish()) return 0;
int ans = 8;
for(int maxd = 1; maxd <ans; maxd++)
if(dfs(0, maxd)) return maxd;
return ans;
}
int main() {
int kass= 0;
while(cin>>n&&n) {
for(int i = 0; i < n; i++) scanf("%d", &a[i]);
printf("Case %d: %d\n", ++kass, solve());
}
return 0;
}
K . Zombie’s Treasure Chest
一开始以为背包问题后来一看范围,那没事了
那就是数学问题,这时候考虑性价比了
取s2件物品1跟取s1件物品2体积一样
然后比较价值
拿(s1*s2)体积取,只能得到某一种物品
然后开始暴力维护最大值得到结果
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
int k,t=0;
scanf("%d",&k);
while(k--){
ll n,s1,s2,v1,v2,x,sum=0;
cin>>n>>s1>>v1>>s2>>v2;
ll s=s1*s2;
v=max(s2*v1,s1*v2);
x=n/s*v;//预处理的价值
n%=s;
if(s1<s2) swap(s1,s2),swap(v1,v2);
for(ll i=0;i<=n/s1;++i){
ll ans=0,m=n;
ans+=i*v1;
m-=i*s1;
ans+=m/s2*v2;
sum=max(sum,ans);
}
sum+=x;
printf("Case #%d: %lld\n",++t,sum);
}
return 0;
}
L . Power Calculus
题目大意:
给定一个数n,让你求从1至少要做多少次乘除才可以从 x 得到 x^n。
跟j一样都差不多是迭代加深算法,也就是剪枝,估价函数
叫IDDFS
估价函数是当前值 << (还剩下的搜索层数)< n
#include<bits/stdc++.h>
using namespace std;
int val[1010]={0};
int pos,d;
int n;
bool dfs(int now)
{
if(now>d) return false;
if(val[pos]<<(d-now)<n)
return false;//估价函数
if(val[pos]==n)
return true;//搜索结束
pos++;
for(int i=0;i<pos;i++)
{
val[pos]=val[pos-1]+val[i];
if(dfs(now+1)) return true;
val[pos]=fabs(val[pos-1]-val[i]);
if(dfs(now+1)) return true;
}
pos--;//重置
return false;
}
int main()
{
while(cin>>n&&n!=0)
{
d=0;
while(true)
{
val[0]=1;
pos=0;
if(dfs(0)) break;
d++;
}
cout<<d<<endl;
}
return 0;
}
M . Lattice Animals
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <set>
#define INF 0x3f3f3f
using namespace std;
const int dx[] = {-1, 1, 0, 0};//方向数组
const int dy[] = {0, 0, -1, 1};
int n, w, h;
int ans[15][15][15];//所有输入对应的答案
struct cell//定义单元格
{
int x, y;
cell(int a, int b)
{
x = a;
y = b;
}
cell(){}
bool operator <(const cell &rhs) const
{
if (x != rhs.x) return x < rhs.x;
return y < rhs.y;
}
};
typedef set<cell> poly;//n个坐标的集合也就是一个n连块
set<poly> vis[15];//用来判重的set,vis[n]是被访问过的所有n连块的集合
poly initial_normal(const poly &p)//将这个n连块标准化成左上角在(0,0)点
{
poly goal;
int minx = INF, miny = INF;
for (cell it : p)
{
minx = min(minx, it.x);
miny = min(miny, it.y);
}
for (cell it : p)
goal.insert((cell){it.x - minx, it.y - miny});
return goal;
}
inline poly rotate(const poly &p)//顺时针旋转转90°,千万记住末尾返回的应该是标准化之后的答案
{ //因为有的n连块顺时针旋转90°之后出界了,需要将其标准化。
poly goal; //因为这个函数会被执行多次,用inline可以加快执行速度
for(poly::iterator i=p.begin(); i!=p.end(); i++)
goal.insert(cell(i->y, -i->x));
return initial_normal(goal);
}
inline poly flip(const poly &p)//将一个n连块沿x轴翻转,同时也要将答案标准化
{
poly goal;
for(poly::iterator i=p.begin(); i!=p.end(); i++)
goal.insert(cell(i->x,-i->y));
return initial_normal(goal);
}
bool had_vis(poly p)//判断一个n连块是否访问过,没访问过就插入到vis里面,返回false
{
int len = p.size();
for (int i=0; i<4; i++)
{
p = rotate(p);
if (vis[len].count(p))
return true;
}
p = flip(p);//将p翻转之后,再次顺时针旋转看出现过没有
for (int i=0; i<4; i++)
{
p = rotate(p);
if (vis[len].count(p))
return true;
}
vis[len].insert(p);
return false;
}
void dfs(const poly &p)//由当前k连块dfs到n连块
{
if (p.size() == n)
{
had_vis(p);
return;
}
for (cell cur : p)
{
for (int d=0; d<4; d++)
{
cell next(cur.x + dx[d], cur.y + dy[d]);
//if(next.x >= 0 && next.x < w && next.y >= 0 && next.y < h && !p.count(next))
//刚开始这里是这样写的,最后答案错误,想了很久才发现。现在的目标不是dfs出
//一个可以装进w*h网格中的n连块,现在的目的是dfs出所有的n连块,所以不在乎能不能装进去
if (!p.count(next))
{
poly p_next = p;
p_next.insert(next);
dfs(p_next);
}
}
}
}
void print_table()//将所有可能的输入打表
{
memset(ans, 0, sizeof(ans));
poly S;
S.insert(cell(0, 0));//得到1连块
vis[1].insert(S);
for (n=2; n<=10; n++)//首先搜索n = 10的情况,这样搜索一遍后,vis里面
{ //就含有了所有大小的连通块。搜索k连块是借用的k-1连块的搜索结果。
for (poly it1 : vis[n - 1])
dfs(it1);
}
for (n=2; n<=10; n++)//对所有可能打表
for (w=1; w<=10; w++)
for (h=1; h<=10; h++)
{
int cnt=0;
for (poly it1 : vis[n])
{
int maxx=0,maxy=0;
for (cell it2 : it1)//寻找当前的连通块的最大的x,y
{
maxx = max(maxx, it2.x);
maxy = max(maxy, it2.y);
}
//能够放入w*h网格内的条件
if(min(maxx, maxy) < min(h, w) && max(maxx, maxy) < max(h, w))
cnt++;
}
ans[n][w][h]=cnt;
}
}
int main()
{
print_table();
while (scanf("%d%d%d", &n, &w, &h)==3)
{
if (n == 1) {printf("1\n");continue;}//1的时候特判
printf("%d\n", ans[n][w][h]);
}
return 0;
}
N . Square Destroyer
#include<bits/stdc++.h>
int n,m,maxd,cnt,sum;
int FullSize[625],Size[625];
bool sti[65],in[625][65];
inline int getc(int r,int c)// | 竖线
{
return r*(2*n+1)+c+n+1;
}
inline int getr(int r,int c)//-- 横线
{
return r*(2*n+1)+c+1;
}
inline int FindNext()//找到下一个没有破坏的正方形
{
for(int i=1;i<=cnt;i++)
if(Size[i]==FullSize[i])
return i;
return 0;
}
void dfs(int d)//深搜
{
if(d>=maxd) return;//最优性剪枝
int next=FindNext();
if(next==0)
{
maxd=d;
return;
}
for(int i=1;i<=sum;i++)
if(in[next][i])
{
for(int j=1;j<=cnt;j++)//删掉火柴棍
if(in[j][i]) Size[j]--;
dfs(d+1);
for(int j=1;j<=cnt;j++)//复原
if(in[j][i]) Size[j]++;
}
}
int main()
{
#ifdef local
freopen("pro.in","r",stdin);
#endif
int kase;
scanf("%d",&kase);
while(kase-->0)
{
memset(in,0,sizeof(in));
memset(sti,1,sizeof(sti));
cnt=0;
scanf("%d%d",&n,&m);
int a,b,e,f;
for(int i=0;i<m;i++)
{
scanf("%d",&a);
sti[a]=0;
}
//状态压缩+预处理
for(int len=1;len<=n;len++)
for(int r=0;r+len<=n;r++)
for(int c=0;c+len<=n;c++)
{
cnt++;
FullSize[cnt]=len*4;
Size[cnt]=0;
for(int i=0;i<len;i++)
{
a=getr(r,c+i);
b=getr(r+len,c+i);
e=getc(r+i,c);
f=getc(r+i,c+len);
in[cnt][a]=true;
in[cnt][b]=true;
in[cnt][e]=true;
in[cnt][f]=true;
Size[cnt]+=sti[a]+sti[b]+sti[e]+sti[f];
}
}
maxd=n*n;//设置上限
sum=2*n*(n+1);
dfs(0);
printf("%d\n",maxd);
}
return 0;
}