CodeVS天梯黄金

2016-8-15~17爆刷水题16道

背景

        2016-8-15~17这三天我抽空刷完了CodeVS天梯黄金难度,一共做了16道题目,大部分是水题,下面是题解

题解

【1098 均分纸牌】

        大家都说这是水题,于是我就深深地感觉智商被侮辱了,这道题初一的时候就不会做,初三的时候想了一天最后也没做出来。现在高二了,终于把它做出来了,然而还是觉得很困难。

        我们求出纸牌的总数,然后除以N,就得到了目标状态时每堆上的纸牌数。我们读入初始状态,然后把初状态中每堆减去这个目标状态。此时对于第i堆纸牌,如果now[i]<0说明这上面需要移过来一些纸牌;=0说明不需要移过来任何纸牌,也不能移出纸牌;>0说明需要移走一些纸牌。

        对于一种非最优解,肯定你几次移动时,某些点既被从左往右经过,又被从右往左经过,这样是一定可以优化到较小的步数的。因此最后的最优方案一定不存在哪个点,使得它既被从左往右经过,又被从右往左经过。这样的话整个从1到N的区间一定可以被分成好多不重合的区间(端点允许重合),每个区间的纸牌数和为0(0是因为我上面减去了平均数),且在每个区间内由大于零的纸牌堆将纸牌移向小于零的纸牌堆。把这种区间划分出来并且最小化每个区间的长度,那么所有区间的长度和就是答案。

        我们从左往右扫描,对于某一个点,假如之前所有的区间的答案都已经统计好了,我们记录一个j,表示最后一个处理完的区间的右端点。用s表示前缀和,那么一定有s[j]==0,假如当前位置是i,当前一定处于某个区间。如果正好s[i]==0,说明i就是区间的右端点,将i-j计入答案;如果s[i]<0,说明还在区间内部,继续扩展;如果s[i]>0,也说明在区间内部,但是我们不是要最小化区间长度吗,这时我们不断往右扩展直到s[i]<0,那么这个点的前一个点就一定有s[i]>=0,这个i就是区间的最右端,这时将i-j计入答案,并且j←i,这时存在两种情况s[j]>0或s[j]=0,如果=0那就不用管了,继续往右进行,如果s[j]>0则将这个数加给下一个数,并且答案+1。

//CodeVS1098 均分纸牌 模拟 
#include <cstdio>
using namespace std;
int s[110], n, a[110];
int main()
{
	int i, j, ans=0, summ=0, k;
	scanf("%d",&n);
	for(i=1;i<=n;i++)scanf("%d",&a[i]),summ+=a[i];
	for(i=1;i<=n;i++)a[i]-=summ/n,s[i]=s[i-1]+a[i];
	a[n+1]=1000;
	for(j=0;a[j+1]==0;j++);
	for(i=j+1;i<=n;i++)
	{
		if(s[i]<0)continue;
		if(s[i]==0)
		{
			ans+=i-j-1;
			j=i;
			continue;
		}
		if(s[i]>0)
		{
			ans+=i-1-j;
			a[i]=s[i];
			for(j=i;s[j]>0;j++);
			a[j]+=s[j-1];
			ans+=j-i;
			for(j--;a[j+1]==0;j++);i=j;
		}
	}
	printf("%d\n",ans);
	return 0;
}

【1214 线段覆盖】

        这道题我想了一个下午都没想出来。后来做了一道叫“线段覆盖2”的题目,只是把这个扩大了范围,我用DP很容易地做出来了。于是我就回来用DP也把这个做出来了。往后翻“3017 线段覆盖2”

//CodeVS1214 线段覆盖 DP
#include <cstdio>
#include <algorithm>
using namespace std;
struct segment
{
	int l, r;
	const bool operator<(segment x)const{return r<x.r;}
}seg[110];
int f[2100], n;
int main()
{
	int i, j;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		scanf("%d%d",&seg[i].l,&seg[i].r);
		seg[i].l+=998;seg[i].r+=998;
		if(seg[i].l>seg[i].r)swap(seg[i].l,seg[i].r);
		seg[i].l++;
	}
	sort(seg+1,seg+n+1);
	j=1;
	for(i=seg[1].r;i<=2000;i++)
	{
		f[i]=f[i-1];
		for(;i==seg[j].r;j++)f[i]=max(f[i],f[i-seg[j].r+seg[j].l-1]+1);
	}
	printf("%d\n",f[2000]);
	return 0;
}

【1014 装箱问题】

        01背包不解释

//CodeVS1014 装箱问题  2001年NOIP全国联赛普及组  01背包 
#include <cstdio>
#include <algorithm>
using namespace std;
int f[35][20005], v, n, V;
int main()
{
	int i, j;
	scanf("%d%d",&V,&n);
	for(i=1;i<=V;i++)f[0][i]=i;
	for(i=1;i<=n;i++)
	{
		scanf("%d",&v);
		for(j=1;j<v;j++)f[i][j]=f[i-1][j];
		for(j=v;j<=V;j++)f[i][j]=min(f[i-1][j],f[i-1][j-v]);
	}
	printf("%d\n",f[n][V]);
	return 0;
}

【1576 最长严格上升子序列】

        这道题描述里让求最长不下降子序列,但其实是求最长严格上升子序列。

        我不想用O(N^2)的算法浪费生命,这道题有O(NlongN)的算法。

        从左往右扫描,假设当前位置是i,用f[j]记录从1道i中长度为j的最长上升子序列的结尾的最小值是多少,

比如长度为3的最长上升子序列当前算出有1 2 8, 1 2 7, 1 2 5,那么f[3]=5。可以很容易地证明f[i]是单调上升的,因为对于一个长度为k的上升子序列a[1]...a[k],假设f[k]=a[k],明显地a[k-1]<a[k],所以f[k-1]最大是a[k-1],而不可能大于或等于a[k-1],也就不可能大于或等于a[k]。

        基于单调性,每次i往右扩展时,就用二分在f数组中找到f[x]<a[i]<f[x+1],并且用f[x+1]=min(f[x+1],a[i]),注意处理好边界。最后所有数全做完时f数组中的元素个数就是答案。

//CodeVS 1576 最长严格上升子序列 专用算法 
#include <cstdio>
#include <algorithm>
using namespace std;
int f[5500], n;
int main()
{
	int i, j, l ,r, mid, K, a;
	scanf("%d%d",&n,&a);
	K=1;
	f[1]=a;
	for(i=2;i<=n;i++)
	{
		scanf("%d",&a);
		l=0;r=K;mid=(l+r+1)>>1;
		while(l<r)
		{
			if(f[mid]<a)l=mid;
			else r=mid-1;
			mid=(l+r+1)>>1;
		}
		l++;
		if(l>K)K=l,f[l]=a;
		f[l]=min(f[l],a);
	}
	printf("%d\n",K);
	return 0;
}

【3027 线段覆盖2】

        按线段(ai,bi)的右端点排序。

        开一个数组f,f[i]表示只考虑完全包含在坐标1到i中的线段的最优解。对于一个点i,对于each线段(aj,bj)(bj==i) f[i]=max{f[i-(bj-aj+1)]+1},对于没有线段右端点的点,f[i]=f[i-1]。

//CodeVS3027 线段覆盖 2 DP
#include <cstdio>
#include <algorithm>
using namespace std;
struct segment
{
	int l, r, w;
}seg[1010];
bool cmp(segment x, segment y)
{
	return x.r<y.r;
}
int f[1000005];
int main()
{
	int i, n, j, a, b, c;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		scanf("%d%d%d",&a,&b,&c);
		seg[i].l=a+1;seg[i].r=b;seg[i].w=c;
	}
	sort(seg+1,seg+n+1,cmp);
	j=1;
	for(i=seg[1].r;i<=1000000;i++)
	{
		f[i]=f[i-1];
		for(;seg[j].r==i;j++)
			f[i]=max(f[i-(seg[j].r-seg[j].l+1)]+seg[j].w,f[i]);
	}
	printf("%d\n",f[1000000]);
	return 0;
}

【1154 能量项链】

        枚举左端点i、右端点j、断点k。

        f[i][j]=max{a[i]*a[k+1]*a[j+1]}

        我程序里枚举的方式不太一样,我是枚举了区间长度、左端点、断点

//CodeVS1154 能量项链  2006年NOIP全国联赛提高组 区间DP
#include <cstdio>
#include <algorithm>
using namespace std;
int n, f[210][210], a[200];
int main()
{
	int i, j, k, ans;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
		scanf("%d",&a[i]),a[n+i]=a[i];
	a[n+n+1]=a[1];
	for(k=2;k<=n;k++)
	{
		for(i=1;i+k-1<=(n<<1);i++)
		{
			for(j=i+1;j<=i+k-1;j++)
				f[i][i+k-1]=max(f[i][i+k-1],
				f[i][j-1]+f[j][i+k-1]+a[i]*a[j]*a[i+k]);
		}
	}
	ans=0;
	for(i=1;i<=n;i++)ans=max(ans,f[i][i+n-1]);
	printf("%d\n",ans);
	return 0;
}

【1166 矩阵取数游戏】

DP很好想,但加上高精就变恶心了。。不过这个高精只需要两个long long就解决了

//CodeVS1166 矩阵取数游戏  2007年NOIP全国联赛提高组 DP+高精
#include <algorithm>
#include <iostream>
#define ll long long
#define limit 1000000000000000ll
using namespace std;
struct bignum
{
	ll a, b;
	bignum(){a=b=0;}
	void show()
	{
		if(a)
		{
			ll cnt=1;
			cout<<a;
			for(ll t=b;t/=10;cnt++);
			cnt=15-cnt;
			while(cnt--)cout<<'0';
			cout<<b;
		}
		else cout<<b<<endl;
	}
	bignum operator+(bignum x)
	{
		bignum t;
		t.b=b+x.b;
		t.a=a+x.a+t.b/limit;
		t.b%=limit;
		return t;
	}
	bignum operator<<(int x)
	{
		bignum t;
		if(x!=1)cerr<<"Error!"<<endl;
		t.b=b<<1;
		t.a=(a<<1)+t.b/limit;
		t.b%=limit;
		return t;
	}
	const bool operator<(bignum x)const
	{
		if(a==x.a)return b<x.b;
		return a<x.a;
	} 
}f[85][85][85], ans, a[85][85];
ll n, m;
int main()
{
	ll i, j, k;
	cin>>n>>m;
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++)
			cin>>a[i][j].b;
	for(k=1;k<=n;k++)
	{
		for(j=1;j<=m;j++)f[k][j][j]=a[k][j]<<1;
		for(i=2;i<=m;i++)
		{
			for(j=1;j+i-1<=m;j++)
			{
				f[k][j][j+i-1]=
				max(f[k][j][j+i-2]+a[k][j+i-1],
					f[k][j+1][j+i-1]+a[k][j]);
				f[k][j][j+i-1]=f[k][j][j+i-1]<<1;
			}
		}
		ans=ans+f[k][1][m];
	}
	ans.show();
	return 0;
}

【1010 过河卒】

        呃。。。。。。

//CodeVS1010 过河卒  2002年NOIP全国联赛普及组 DP
#include <cstdio>
#include <algorithm>
using namespace std;
int f[25][25], horse[25][25], x, y, n, m;
int main()
{
	int i, j;
	scanf("%d%d%d%d",&n,&m,&x,&y);
	if(x-1>=0)
	{
		if(y-2>=0)horse[x-1][y-2]=true;
		if(y+2<=m)horse[x-1][y+2]=true;
	}
	if(x-2>=0)
	{
		if(y-1>=0)horse[x-2][y-1]=true;
		if(y+1<=n)horse[x-2][y+1]=true;
	}
	if(x+1<=m)
	{
		if(y-2>=0)horse[x+1][y-2]=true;
		if(y+2<=n)horse[x+1][y+2]=true;
	}
	if(x+2<=m)
	{
		if(y-1>=0)horse[x+2][y-1]=true;
		if(y+1<=n)horse[x+2][y+1]=true;
	}
	horse[x][y]=true;
	f[0][0]=1;
	for(i=1;i<=n;i++)f[i][0]=(f[i-1][0]&&!horse[i][0]);
	for(j=1;j<=m;j++)f[0][j]=(f[0][j-1]&&!horse[0][j]);
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++)
			if(!horse[i][j])f[i][j]=f[i-1][j]+f[i][j-1];
	printf("%d\n",f[n][m]);
	return 0;
}

【1169 传纸条】

        四维DP,枚举两个点然后统计方案数,枚举时为了方便可以让一个点的纵坐标大于另一个点,这样能省很多代码。

        当两个点相邻时,由于你让后一个点的纵坐标大于第一个点,所以只有三种情况,这时为了避免路线相交要单独讨论。

        其余的时候直接递推就行了。

//CodeVS1169 传纸条  2008年NOIP全国联赛提高组 DP
#include <cstdio>
#include <algorithm>
#define ll long long
#define maxn 51
using namespace std;
int f[maxn][maxn][maxn][maxn], kindness[maxn][maxn];
int main()
{
	int a, b, x, y, n, m;
	scanf("%d%d",&n,&m);
	for(a=1;a<=n;a++)
		for(b=1;b<=m;b++)
			scanf("%d",&kindness[a][b]);
	for(a=1;a<=n;a++)
		for(b=1;b<=m;b++)
		{
			for(x=a;x<=n;x++)
				for(y=1;y<=m;y++)
				{
					if(a==x&&y==b)continue;
					else if(a+1==x&&y==b)
						f[a][b][x][y]=
						max(f[a-1][b][x][y-1],f[a][b-1][x][y-1]);
					else if(a==x&&y==b+1)
						f[a][b][x][y]=
						max(f[a][b-1][x-1][y],f[a-1][b][x-1][y]);
					else if(a==x&&y==b-1)
						f[a][b][x][y]=
						max(f[a-1][b][x-1][y],f[a][b-1][x-1][y]);
					else
						f[a][b][x][y]=max(
						max(f[a-1][b][x-1][y],f[a-1][b][x][y-1]),
						max(f[a][b-1][x-1][y],f[a][b-1][x][y-1]));
					f[a][b][x][y]+=kindness[a][b]+kindness[x][y];
				}
		}
	printf("%d\n",f[n-1][m][n][m-1]);
	return 0;
}

【1219 骑士游历】

        这是道好题,你发现想算一个点就要算出它左侧的好多点,因此你可以一列一列的枚举。不过我选的方法是记忆化搜索。

//CodeVS1219 骑士游历  1997年 DP
#include <cstdio>
#include <algorithm>
#include <cstring>
#define ll long long
using namespace std;
ll dp[60][60], n, m, x1, y1, x2, y2;
bool f(ll x, ll y)
{
	return x>0&&x<=n&&y>0&&y<=m;
}
ll dfs(ll x, ll y)
{
	if(dp[x][y]!=-1)return dp[x][y];
	dp[x][y]=0;
	if(f(x-2,y-1))dp[x][y]+=dfs(x-2,y-1);
	if(f(x-1,y-2))dp[x][y]+=dfs(x-1,y-2);
	if(f(x+2,y-1))dp[x][y]+=dfs(x+2,y-1);
	if(f(x+1,y-2))dp[x][y]+=dfs(x+1,y-2);
	return dp[x][y];
}
int main()
{
	scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&y1,&x1,&y2,&x2);
	memset(dp,-1,sizeof(dp));
	dp[x1][y1]=1;
	printf("%lld\n",dfs(x2,y2));
	return 0;
}

【1220 数字三角形】

        三次才过啊。。有没有搞错

        这道题最黑的地方就是有负权的点

//CodeVS1220 数字三角形
#include <cstdio>
#include <algorithm>
using namespace std;
int f[110][110], n;
int main()
{
	int i, j, ans;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
		for(j=i+1;j<=n;j++)
			f[i][j]=-0x7fffffff;
	for(i=1;i<=n;i++)
		for(j=1;j<=i;j++)
		{
			scanf("%d",&f[i][j]);
			f[i][j]+=max(f[i-1][j],f[i-1][j-1]);
		}
	ans=-0x7fffffff;
	for(i=1;i<=n;i++)ans=max(ans,f[n][i]);
	printf("%d\n",ans);
	return 0;
}

【1040 统计单词个数】

        不管什么东西,一加上“单词”就变恶心了。。。

        先做N^2的预处理,算出s[i][j]表示区间i到j的单词个数(看代码,做两次for循环)

        然后从左往右做DP,枚举当前放几个分隔符,再枚举最后一个分隔符的位置。具体方程就不写了。

//CodeVS1040 统计单词个数  2001年NOIP全国联赛提高组 DP
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char str[210], dic[10][200];
int  p, k,  f[210][50], s, T, len, cnt[210][210];
int compare(int pos)
{
	int i, j, minl=1000;
	for(i=1;i<=s;i++)
	{
		for(j=1;str[pos+j-1]==dic[i][j];j++);
		if(j==dic[i][0]+1)minl=min(minl,(int)dic[i][0]);
	}
	return minl;
}
int main()
{
	int i, j, maxl, minl, ii, x;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&p,&k);
		for(i=0;i<p;i++)scanf("%s",str+1+i*20);
		scanf("%d",&s);
		for(i=1;i<=s;i++)
			scanf("%s",dic[i]+1),dic[i][0]=strlen(dic[i]+1);
		str[(len=p*20)+1]='A';
		for(i=1;i<=len;i++)
			for(j=1;j<=i;j++)cnt[1][i]+=(compare(j)<=i-j+1);
		for(i=2;i<=len;i++)
			for(j=2;j<=i;j++)
			{
				cnt[j][i]=cnt[j-1][i];
				if(compare(j-1)<=i-(j-1)+1)cnt[j][i]--;
			}
		k--;
		for(i=1;i<=len;i++)f[i][0]=cnt[1][i];
		for(ii=1;ii<=k;ii++)
			for(i=1;i<=len;i++)
				for(j=i-1;j>=ii+1;j--)f[i][ii]=max(f[i][ii],f[j][ii-1]+cnt[j+1][i]);
		printf("%d\n",f[len][k]);
	}
	return 0;
}

【1004 四子连棋】

        爆搜

//CodeVS1004 四子连棋 搜索
#include <cstdio>
#include <algorithm>
#define other(x) (x=='W'?'B':'W')
#define inf 0x7fffffff
using namespace std;
char now[6][6];
int xw1, yw1, xw2, yw2, ans=1000;
bool check()
{
	int i;
	for(i=1;i<=4;i++)
		if(now[i][1]==now[i][2]&&now[i][2]==now[i][3]&&now[i][3]==now[i][4]
		 ||now[1][i]==now[2][i]&&now[2][i]==now[3][i]&&now[3][i]==now[4][i])
		 return true;
	if(now[1][1]==now[2][2]&&now[2][2]==now[3][3]&&now[3][3]==now[4][4]
	 ||now[1][4]==now[2][3]&&now[2][3]==now[3][2]&&now[3][2]==now[4][1])
	 	return true;
	return false;
}
void chg(char &x, char &y)
{
	char t=x;x=y;y=t;
}
void dfs(char color, int deep)
{
	char t;
	if(deep>ans)return;
	if(check())ans=min(ans,deep);
	if(now[xw1-1][yw1]==color)
		chg(now[xw1][yw1],now[xw1-1][yw1]),xw1--,
		dfs(other(color),deep+1),xw1++,chg(now[xw1][yw1],now[xw1-1][yw1]);
	if(now[xw1+1][yw1]==color)
		chg(now[xw1][yw1],now[xw1+1][yw1]),xw1++,
		dfs(other(color),deep+1),xw1--,chg(now[xw1][yw1],now[xw1+1][yw1]);
	if(now[xw1][yw1-1]==color)
		chg(now[xw1][yw1],now[xw1][yw1-1]),yw1--,
		dfs(other(color),deep+1),yw1++,chg(now[xw1][yw1],now[xw1][yw1-1]);
	if(now[xw1][yw1+1]==color)
		chg(now[xw1][yw1],now[xw1][yw1+1]),yw1++,
		dfs(other(color),deep+1),yw1--,chg(now[xw1][yw1],now[xw1][yw1+1]);
	
	if(now[xw2-1][yw2]==color)
		chg(now[xw2][yw2],now[xw2-1][yw2]),xw2--,
		dfs(other(color),deep+1),xw2++,chg(now[xw2][yw2],now[xw2-1][yw2]);
	if(now[xw2+1][yw2]==color)
		chg(now[xw2][yw2],now[xw2+1][yw2]),xw2++,
		dfs(other(color),deep+1),xw2--,chg(now[xw2][yw2],now[xw2+1][yw2]);
	if(now[xw2][yw2-1]==color)
		chg(now[xw2][yw2],now[xw2][yw2-1]),yw2--,
		dfs(other(color),deep+1),yw2++,chg(now[xw2][yw2],now[xw2][yw2-1]);
	if(now[xw2][yw2+1]==color)
		chg(now[xw2][yw2],now[xw2][yw2+1]),yw2++,
		dfs(other(color),deep+1),yw2--,chg(now[xw2][yw2],now[xw2][yw2+1]);
}
int main()
{
	int i, j;
	for(i=1;i<=4;i++)scanf("%s",now[i]+1);
	for(i=1;i<=4;i++)
		for(j=1;j<=4;j++)
			if(now[i][j]=='O')
				if(xw1)xw2=i,yw2=j;
				else xw1=i,yw1=j;
	dfs('B',0);
	dfs('W',0);
	printf("%d\n",ans);
	return 0;
}

【1099 字串变换】

        这个可以BFS。C++选手使用了string和map,给pascal选手造成了致命一击。

//CodeVS1099 字串变换  2002年NOIP全国联赛提高组 搜索
#include <cstdio>
#include <string>
#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
using namespace std;
struct str
{
	string s;
	int deepth;
};
queue<str> q;
string A, B, a[10], b[10];
map<string,bool> used;
int ans, tot;
bool cmp(string s, int pos, string t)
{
	int i;
	for(i=0;i<t.length()&&pos+i<s.length()&&s[pos+i]==t[i];i++);
	return i==t.length();
}
void split(string s, int pos, string &s1, string &s2)
{
	int i;
	s1.clear();s2.clear();
	for(i=0;i<=pos;i++)s1+=s[i];
	for(;i<s.length();i++)s2+=s[i];
}
int BFS()
{
	int i, j;
	str t;
	string s1, s2, s3;
	q.push((str){A,0});
	while(!q.empty())
	{
		t=q.front();q.pop();
		if(t.s==B)return t.deepth;
		if(t.deepth==10)continue;
		for(i=0;i<t.s.length();i++)
		{
			for(j=1;j<=tot;j++)
			{
				if(cmp(t.s,i,a[j]))
				{
					split(t.s,i-1,s1,s2);
					split(t.s,i+a[j].length()-1,s2,s3);
					s1=s1+b[j]+s3;
					if(!used[s1])
					{
						used[s1]=true;
						q.push((str){s1,t.deepth+1});
					}
				}
			}
		}
	}
	return -1;
}
int main()
{
	cin>>A>>B;
	while(!cin.eof())
		cin>>a[tot]>>b[++tot];
	tot--;
	ans=BFS();
	if(ans==-1)cout<<"NO ANSWER!\n"<<endl;
	else cout<<ans<<endl;
	return 0;
}

【1116 四色问题】

        爆搜

//CodeVS1116 四色问题 搜索
#include <cstdio>
#include <algorithm>
using namespace std;
int map[10][10], color[10], ans, n;
void dfs(int now)
{
	if(now>n){ans++;return;}
	bool used[5]={0};
	int i;
	for(i=1;i<=n;i++)if(map[now][i])used[color[i]]=true;
	for(i=1;i<=4;i++)
		if(!used[i])
		{
			color[now]=i;
			dfs(now+1);
		}
	color[now]=0;
}
int main()
{
	int i, j;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			scanf("%d",&map[i][j]);
	dfs(1);
	printf("%d\n",ans);
	return 0;
}

【1294 全排列】

        。。。。。

//CodeVS1294 全排列 搜索 
#include <cstdio>
#include <algorithm>
using namespace std;
int used[15], n, s[15];
void dfs(int deep)
{
	int i;
	if(deep>n)
	{
		for(i=1;i<=n;i++)printf("%d ",s[i]);
		printf("\n");
		return;
	}
	for(i=1;i<=n;i++)
		if(!used[i])
		{
			used[i]=true;
			s[deep]=i;
			dfs(deep+1);
			used[i]=false;
		}
}
int main()
{
	scanf("%d",&n);
	dfs(1);
	return 0;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值