火柴棍等式
不知道为什么错了的搜索。。。
#include<bits/stdc++.h>
using namespace std;
const int a[]={6,2,5,5,4,5,6,3,7,6};
int ans,n,e[2002];
void dfs(int sum,int x,int val,int bef,int he,int op,int sit)
{
//cout<<sum<<" "<<x<<" "<<val<<" "<<he<<" "<<op<<endl;
for(int i=0;i<10;i++)
if(a[i]<=sum-x) dfs(sum,x+a[i],val*10+i,bef,he,op,sit);
if(x-sum==0)
{
if(op==1)
for(int i=sum+2;i<=n-2;i++) dfs(i,x,0,bef,val,2,sit);
if(op==2) {if(bef==val) dfs(n,x,0,bef,he+val,3,1); else dfs(n,x,0,bef,he+val,3,0);}
if(op==3)
if(he==val)
{
if(sit==1) e[bef]=1;
else ans++;
}
}
}
int main()
{
scanf("%d",&n); n-=4;
for(int i=2;i<=n-4;i++) dfs(i,0,0,0,0,1,0);
for(int i=0;i<=2001;i++) if(e[i]) ans++;
cout<<ans<<endl;
return 0;
}
正解(很巧妙,没想到,copy自洛谷第一篇题解)
#include<stdio.h>
int main()
{
int a[2001]={6},b,c[10]={6,2,5,5,4,5,6,3,7,6},s=0,i,j;
scanf("%d",&b);
for(i=1;i<=2000;i++)
{
j=i;
while(j>=1)//求每个数所用的火柴棒
{
a[i]=a[i]+c[j%10];
j=j/10;
}
}
for(i=0;i<=1000;i++)
{
for(j=0;j<=1000;j++)
if(a[i]+a[j]+a[i+j]+4==b)s++;//还有加号与等号
}
printf("%d",s);
return 0;
}
双栈排序
好难,想不到;
先考虑一个栈,题解里都只是给出了一个结论:对于i<j<k,存在a[k]<a[i]<a[j],则i,j不能放进一个栈里(题解只证了必要性,我觉得要证充分性才行,但我不会)
然后就是二分图的标准建模了,把所有的i,j不能放进栈里的连一条边,然后染色,为1的放进第一个栈,为2的放进第二个栈,如果不是二分图就是无解;
code
#include<bits/stdc++.h>
using namespace std;
const int N=1010,inf=0x3f3f3f3f;
int read()
{
int x=0,p=1; char ch=getchar();
while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
if(ch=='-') p=-1,ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return x*p;
}
queue<int> Q;
int a[N],f[N],stk1[N],stk2[N],e[N][N],col[N];
int n,top1,top2,now=1;
void bfs(int t)
{
while(Q.size()) Q.pop();
Q.push(t); col[t]=1;
while(Q.size())
{
int x=Q.front(); Q.pop();
for(int i=1;i<=n;i++)
if(e[x][i])
{
if(col[i]==col[x]) { puts("0"); exit(0);}
if(!col[i]) { col[i]=3-col[x]; Q.push(i); }
}
}
}
void print1(int x)
{
while(top1 && a[x]>stk1[top1]) { printf("b "); top1--; }
stk1[++top1]=a[x];
printf("a ");
}
void print2(int x)
{
while(top2 && a[x]>stk2[top1]) { printf("d "); top2--; }
stk2[++top2]=a[x];
printf("c ");
}
int main()
{
n=read();
f[n+1]=inf;
for(int i=1;i<=n;i++) a[i]=read();
for(int i=n;i>=1;i--) f[i]=min(a[i],f[i+1]);
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(a[i]<a[j] && f[j+1]<a[i]) e[i][j]=e[j][i]=1;
for(int i=1;i<=n;i++) if(!col[i]) bfs(i);
for(int i=1;i<=n;i++)
{
if(col[i]==1)
{
stk1[++top1]=a[i];
printf("a ");
}
else {
stk2[++top2]=a[i];
printf("c ");
}
while((top1 && stk1[top1]==now) || (top2 && stk2[top2]==now))
{
if(top1 && stk1[top1]==now)
{
top1--;
now++;
printf("b ");
}
else
{
top2--;
now++;
printf("d ");
}
}
}
return 0;
}
后面模拟我本来是这样写的,但错了
void print1(int x)
{
while(top1 && a[x]>stk1[top1]) { printf("b "); top1--; }
stk1[++top1]=a[x];
printf("a ");
}
void print2(int x)
{
while(top2 && a[x]>stk2[top1]) { printf("d "); top2--; }
stk2[++top2]=a[x];
printf("c ");
}
for(int i=1;i<=n;i++)
if(col[i]==1) print1(i);
else print2(i);
while(top1) { printf("b "); top1--; }
while(top2) { printf("d "); top2--; }