/*P1498 南蛮图腾
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
int n;
char a[5][5],b[3000+10][3000+10];
int main()
{
cin>>n;
memset(a,' ',sizeof(a));
memset(b,' ',sizeof(b));
}*/
/*P1049 装箱问题
#include <iostream>
using namespace std;
int a[30+1];
int main()
{
int n,m;
cin>>m>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
return 0;
}*/
/*P1885 Moo(错误)
#include <iostream>
#include <cstring>
using namespace std;
int n,len=0;
string a;
string f(int k);
int Len(int k);
int main()
{
cin>>n;
f(n);
Len(n);
cout<<a[len-1]<<endl;
return 0;
}
int Len(int k)
{
if(len>=n)
return len;
else {
if(k==0) len=3;
else
{
len=2*Len(k-1)+1+k+2;
}
}
}
string f(int k)
{
if(k==0) return a="moo";
else{
string b="moo";
for(int i=1;i<=k;i++)
{
b=b+"o";
}
return a=f(k-1)+b+f(k-1);
}
}
*/
/*P1464 Function(有bug,没找到)
#include <iostream>
#include <cstring>
using namespace std;
#define ll long long int
ll w(ll a,ll b,ll c);
ll x[25][25][25];
int main()
{
ll a,b,c;
while(cin>>a>>b>>c)
{
if(a==-1&&b==-1&&c==-1) break;
memset(x,0,sizeof(x));
if(a>20) a=21;
if(b>20) b=21;
if(c>20) c=21;
cout<<"w("<<a<<", "<<b<<", "<<c<<") = "<< w(a,b,c)<<endl;
}
return 0;
}
ll w(ll a,ll b,ll c)
{
if(a<=0||b<=0||c<=0) return 1;
else if(x[a][b][c]!=0) return x[a][b][c];
else if(a>20||b>20||c>20) return x[a][b][c]=w(20,20,20);
else if(a<b&&b<c) return x[a][b][c]=w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c);
else return x[a][b][c]=w(a-1,b,c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1,b-1,c-1);
}*/
/*P1657 选书
#include <iostream>
using namespace std;
int n,total=0;
int a[100][3];
int b[100];
void f(int x);
int main()
{
cin>>n;
if(n==0) cout<<0<<endl;
else{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=2;j++)
{
cin>>a[i][j];
b[a[i][j]]=0;
}
}
f(1);
cout<<total<<endl;
}
return 0;
}
void f(int x)
{
if(x==n+1)
total++;
else{
for(int j=1;j<=2;j++)
{
if(b[a[x][j]]==0)
{
b[a[x][j]]=1;
f(x+1);
b[a[x][j]]=0;
}
}
}
}
*/
/*传球游戏
#include <iostream>
using namespace std;
int n,m,sum= 0;
void f(int k,int step);
int main()
{
cin>>n>>m;
f(1,0);
cout<<sum<<endl;
return 0;
}
void f(int k,int step)
{
if(step==m)
{
if(k==1) sum++;
}
else {
if(k==1)
{
f(k+1,step+1);
f(n,step+1);
}
else if(k==n)
{
f(n-1,step+1);
f(1,step+1);
}
else{
f(k+1,step+1);
f(k-1,step+1);
}
}
}
*/
/*油桶问题
#include <iostream>
using namespace std;
int n,m;
int a[1000+10];
bool f(int n,int m);
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
if(f(n,m)==1) cout<<"yes"<<endl;
else cout<<"no"<<endl;
return 0;
}
bool f(int n,int m)
{
if(a[n]==m)
return 1;
else{
if(f(n-1,m-a[n])==1)
{
return 1;
}
if(f(n-1,m)==1)
{
return 1;
}
}
return 0;
}
*/
/*数字三角形的递归算法
#include <iostream>
#include <cstring>
using namespace std;
int n;
int a[1000+10][1000+10];
int f(int x,int y);
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
a[i][j]=0;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
cin>>a[i][j];
}
}
cout<<f(1,1)<<endl;;
return 0;
}
int f(int x,int y)
{
int left,right;
if(x==n)
return a[x][y];
left=f(x+1,y);
right=f(x+1,y+1);
if(left>right)
return left+a[x][y];
else
return right+a[x][y];
}
*/
/*求子集的位运算法
#include <iostream>
using namespace std;
int n;
void f(int n);
int main()
{
cin>>n;
cout<<"()"<<endl;
for(int i=1;i<(1<<n);i++)
{
f(i);
}
return 0;
}
void f(int n)
{
cout<<"(";
for(int i=0;i<n;i++)
{
if((1<<i)&n)
{
cout<<char(i+'a')<<" ";
}
}
cout<<")"<<endl;
}
*/
/*求子集的递归算法
#include <iostream>
using namespace std;
int n;
int a[100+10];
void f(int k);
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
a[i]=-1;
}
f(1);
return 0;
}
void f(int k)
{
for(int i=0;i<=1;i++)
{
a[k]=i;
if(k==n)
{
cout<<"(";
for(int i=1;i<=n;i++)
{
if(a[i]==1)
cout<<char('a'+i-1)<<" ";
}
cout<<")"<<endl;
}
else f(k+1);
}
}
*/
/*n皇后求摆法数的位运算法
#include <iostream>
using namespace std;
int lim,sum;
void test(int row,int left,int right)
{
int pos,p;
if(row!=lim)
{
pos=lim&~(row|left|right);
while(pos!=0)
{
p=pos&-pos;
pos=pos-p;
test(row+p,(left+p)<<1,(right+p)>>1);
}
}
else sum++;
}
int main()
{
int n;
cin>>n;
lim=(1<<n)-1;//n个1
test(0,0,0);
cout<<sum<<endl;
return 0;
}*/
/*位运算测试
#include <iostream>
using namespace std;
int main()
{
int a=-10;
cout<<(~a)<<endl;
int a[10];
for(int i=1;i<=5;i++)
{
cin>>a[i];
}
int sum=0;
for(int i=1;i<=5;i++)
{
sum=(sum^a[i]^a[i]);
}
int x=5;
cout<<(x^sum)<<endl;
return 0;
}*/
/*
位运算法
二进制的进位规则:逢二进一
二进制的借位规则:借一当二
二进制加法
二进制减法
原码:第一位上面是零表示正数,第一位上面是一表示负数
反码:正数和原码相同,负数是原码除第一位之外其它位都按位取反
补码:正数和原码相同,负数是补码加一
补码的加减法
位运算符:~,&<<>>,|^(按优先级排列)
位运算符的优先性很低,必须加括号
按位与运算符:&
如果两个相应的位都为1,则该位的结果值为1,否则为0
0&0=0;0&1=0;1&0=0;1&1=1;
按位与运算通常用于二进制取位操作
一个数&1的结果就是取二进制的最末位,可以用来判断一个整数的奇偶
按位或运算符:|
如果两个相应的位有一个为1,则该位的结果值为1,否则为0
0|0=0;0|1=1;1|0=1;1|1=1;
按位或运算通常用于二进制特定位上的无条件赋值
一个数|1的结果就是把二进制最末尾强行变为一,一个数|1之后再减1就可以把这个数变成最接近原数的偶数
异或运算符:^
如果两个相应的位同号,则该位的结果值为0,否则为1
0^0=0;0^1=1;1^0=1;1^1=0;
两次异或同一个数最后结果不变,异或运算可以用于简单的加密
异或可以交换两个整数(局限性极大)
相同数字异或结果为0,0异或任何数就等于任何数
取反运算符:~
所有位都取反,1变成0,0变成1
正数a变负数,无符号型变成-a,有符号型变成-a-1
负数b变正数,无符号型无负数,有符号型变成-b-1
左移运算符:<<
A<<B,表示所有的二进制位整体向左移动b位,后面B位用0补充
a<<1,相当于a*2
右移运算符:>>
A>>B,表示所有的二进制位整体向右移动b位,前面B位用0补充
a>>1,相当于a/2
只能用于正数
*/
/*n皇后问题
abs是求整型数据绝对值的函数,头文件是math.h,stdlib.h
fab是求浮点型数绝对值的函数,头文件是math.h
#include <iostream>
#include <cstdlib>
#include <cstdlib>
using namespace std;
int n,a[20];
int Try(int x,int y);
void f(int x);
int main()
{
cin>>n;
f(1);
return 0;
}
void f(int x)
{
int y;
if(x>n)
{
for(int i=1;i<=n;i++)
{
cout<<a[i];
}
cout<<endl;
}
else {
for(y=1;y<=n;y++)
{
if(Try(x,y)==1)
{
a[x]=y;
f(x+1);
}
}
}
}
int Try(int x,int y)
{
int i;
for(i=1;i<x;i++)
{
if(a[i]==y||((abs(i-x))==abs(a[i]-y)))
{
break;
}
}
if(i>=x) return 1;
else return 0;
}
*/
/*分形图2(有错误,未解决)
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
int n;
char a[10][10];
char b[1000+10][1000+10];
void f(int k,int x,int y);
int main()
{
while(cin>>n)
{
if(n==0||n==EOF) break;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>a[i][j];
}
}
int m;
cin>>m;
int len=pow(n*1.0,m);
for(int i=1;i<=len;i++)
{
for(int j=1;j<=len;j++)
{
b[i][j]=' ';
}
}
f(m,1,1);
for(int i=1;i<=len;i++)
{
for(int j=1;j<=len;j++)
{
cout<<b[i][j];
}
}
}
return 0;
}
void f(int k,int x,int y)
{
if(k==1)
{
for(int i=x+0;i<n+x;i++)
{
for(int j=y+0;j<n+y;j++)
{
b[i][j]=a[i-x+1][j-y+1];
}
}
}
else{
int sum=1;
int kk=k-2;
while(kk--)
sum=sum*n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i][j]!=' ')
{
f(k-1,x+sum*n*i,y+sum*n*j);
}
}
}
}
}*/
/*pow函数
文件:math.h/cmath(C++中)
功能:计算x的y次幂。
返回值:x不能为负数且y为小数,或者x为0且y小于等于0,返回幂指数的结果。
返回类型:double型,int,float会给与警告!*/
/*分形图
#include <iostream>
#include <cmath>
using namespace std;
int n,m;
char a[1000+10][1000+10];
void f(int n,int x,int y);
int main()
{
while(cin>>n)
{
if(n==-1) break;
m=pow(3.0,n-1);
for(int i=1;i<=m;i++)
{
for(int j=1;j<=m;j++)
{
a[i][j]=' ';
}
}
f(n,1,1);
for(int i=1;i<=m;i++)
{
for(int j=1;j<=m;j++)
{
cout<<a[i][j];
}
cout<<endl;
}
cout<<"-"<<endl;
}
return 0;
}
void f(int n,int x,int y)
{
int z;
if(n==1)
a[x][y]='x';
else{
z=pow(3.0,n-2);
f(n-1,x,y);
f(n-1,x,y+2*z);
f(n-1,x+z,y+z);
f(n-1,x+2*z,y);
f(n-1,x+2*z,y+2*z);
}
}
*/
/*拆分自然数的回溯算法
#include <iostream>
using namespace std;
int n,total=0;
int num[100]={0};
void f(int n,int k);
int main()
{
cin>>n;
f(n,1);
cout<<total<<endl;
return 0;
}
void f(int n,int k)
{
int x;
for(int i=1;i<=n;i++)
{
if(i>=num[k-1])
{
num[k]=i;
x=n-i;
if(x==0&&k>1)
{
cout<<n<<"="<<num[1];
for(int i=2;i<=k;i++)
{
cout<<"+"<<num[i];
}
cout<<endl;
total++;
}
else
f(x,k+1);
num[k]=0;
}
}
}*/
/*对于某个问题一时无法下手时,
可以通过一些简单的实例进行分析
以寻找规律*/
/*回溯法*/
/*拆分自然数的递归算法
#include <iostream>
using namespace std;
int num[100],count=0;
void f(int k,int n);
int main()
{
cin>>num[0];
for(int i=1;i<=num[0]/2;i++)
{
num[1]=i;
f(1,num[0]-num[1]);
}
cout<<count<<endl;
return 0;
}
void f(int k,int n)
{
if(n<1)
{
cout<<num[0]<<"="<<num[1];
for(int i=2;i<=k;i++)
cout<<"+"<<num[i];
cout<<endl;
count++;
}
else
{
for(int i=num[k];i<=n;i++)//存疑,倒过来怎么算
{
if(i>=num[k]){
num[k+1]=i;
f(k+1,n-num[k+1]);
}
if(i<=n){
num[k+1]=i;
f(k+1,n-num[k+1]);
}
}
}
}
*/
/*地盘划分的优化递归算法
#include <iostream>
using namespace std;
int sum=0;
int f1(int x,int y);
int f2(int x,int y);
int main()
{
int x,y;
cin>>x>>y;
f1(x,y);
cout<<sum<<endl;
cout<<f2(x,y)<<endl;
return 0;
}
int f2(int x,int y)
{
if(x>y)
{
int t=x;
x=y;
y=t;
}
if(y%x==0) return y/x;
else
{
int a=x;
int b=y;
y=y%x;
return f2(x,y)+b/a;
}
}
int f1(int x,int y)
{
if(x>y)
{
int t=y;
y=x;
x=t;
}
if(y%x==0) return sum=sum+y/x;
else {
sum=sum+y/x;
x=x;
y=y%x;
f1(x,y);
}
}*/
/*地盘划分的朴素递归算法
#include <iostream>
using namespace std;
int sum=0;
int f(int x,int y);
int main()
{
int x,y;
cin>>x>>y;
f(x,y);
cout<<sum<<endl;
return 0;
}
int f(int x,int y)
{
if(x==y) return sum++;
else
{
if(x>y)
{
x=x-y;
sum++;
f(x,y);
}
else
{
y=y-x;
sum++;
f(x,y);
}
return sum;
}
}
*/
/*棋子移动
#include <iostream>
using namespace std;
int f(int n);
int main()
{
int n;
cin>>n;
f(n);
return 0;
}
int f(int n)
{
if(n==4)
{
cout<<"4,5-->9,10"<<endl;
cout<<"8,9-->4,5"<<endl;
cout<<"2,3-->8,9"<<endl;
cout<<"7,8-->2,3"<<endl;
cout<<"1,2-->7,8"<<endl;
}
else
{
cout<<n<<","<<n+1<<"-->"<<2*n+1<<","<<2*n+2<<endl;
cout<<2*n-1<<","<<2*n<<"-->"<<n<<","<<n+1<<endl;
f(n-1);
}
}*/
算法竞赛宝典-递归算法
最新推荐文章于 2023-09-02 13:01:55 发布