对每个输入的整数n,用分治法计算并输出1…n的全排列。
void perm(int a[],int x,int y){
if(x==y){
fer(i,0,y)cout<<a[i]<<" ";
cout<<endl;
}else{
fer(i,x,y){
swap(a[i],a[x]);
perm(a,x+1,y);
swap(a[i],a[x]);
}
}
}
signed main(){
int a[7];
fer(i,0,7)a[i]=i+1;
int n;
while(cin>>n){
perm(a,0,n);
}
return 0;
}
我们要求找出具有下列性质数的个数(包含输入的自然数n)。
先输入一个自然数 n (n≤1000),然后对此自然数按照如下方法进行处理:
1· 不作任何处理,计数
2. 在它的左边加上一个不超过原数的一半的自然数;
3.新的原数是这个加上去的自然数,继续按此规则进行处理,直到不能再加自然数为止。
递归(TLE)
int cnt=0;
void solve(int n){
cnt+=n/2;
fer(i,1,n/2+1){
solve(i);
}
}
signed main(){
int n;cin>>n;
solve(n);
cout<<cnt;
return 0;
}
记忆化搜索
int a[10000];
void solve(int n){
if(a[n]!=-1)return;
a[n]=1;
fer(i,1,n/2+1){
solve(i);
a[n]+=a[i];
}
}
signed main(){
int n;cin>>n;
fer(i,1,n+1){
a[i]=-1;
}
solve(n);
cout<<a[n];
return 0;
}
大于1的正整数可以分解成一组因子的乘积,例如12可以分解成:12、6x2、4x3、3x4、3x2x2、2x6、2x3x2、2x2x3,共8个分解式。请设计算法,计算指定的大于1的正整数的分解式的个数。
int cnt;
void solve(int x){
if(x==1){
cnt++;return;
}
fer(i,2,x+1){
if(x%i==0){
solve(x/i);
}
}
}
signed main(){
cf{
int n;cin>>n;
cnt=0;
solve(n);
cout<<cnt<<endl;
}
return 0;
}
对序列X=(x1, x2, …, xm),定义其子序列为(xi1, xi2, …, xik),i1
string a,b;
int solve(int i,int j){
if(i==-1||j==-1)return 0;
if(a[i]==b[j])return solve(i-1,j-1)+1;
else return max(solve(i-1,j),solve(i,j-1));
}
signed main(){
while(cin>>a>>b){
int lena=a.size(),lenb=b.size();
cout<<solve(lena-1,lenb-1)<<endl;
}
return 0;
}
动态规划 AC
string a,b;
int cnt[101][101];
void solve(int i,int j){
fer(s,1,i+1){
fer(k,1,j+1){
if(a[s-1]==b[k-1]){
cnt[s][k]=cnt[s-1][k-1]+1;
}else{
cnt[s][k]=max(cnt[s-1][k],cnt[s][k-1]);
}
}
}
}
signed main(){
while(cin>>a>>b){
fer(i,0,101){
fer(j,0,101)cnt[i][j]=0;
}
int lena=a.size(),lenb=b.size();
solve(lena,lenb);
cout<<cnt[lena][lenb]<<endl;
}
return 0;
}
int a[N];
int partition(int a[],int l,int r){
int i=l,j=r;
int x=a[l];
while(i<j){
while(i<j&&a[j]>=x)j--;
a[i]=a[j];
while(i<j&&a[i]<=x)i++;
a[j]=a[i];
}
a[i]=x;
return j;
}
void quicksort(int a[],int l,int r){
int t;
if(l<r){
t=partition(a,l,r);
quicksort(a,l,t-1);
quicksort(a,t+1,r);
}
}
signed main(){
int n;cin>>n;
fer(i,0,n)cin>>a[i];
quicksort(a,0,n-1);
fer(i,0,n)cout<<a[i]<<" ";
cout<<endl;
return 0;
}
【题目描述】
有2n个棋子(n≥4)排成一行,开始位置为白子全部在左边,黑子全部在右边,如下图为n=5的情形:
○○○○○●●●●●
移动棋子的规则是:每次必须同时移动相邻的两个棋子,颜色不限,可以左移也可以右移到空位上去,但不能调换两个棋子的左右位置。每次移动必须跳过若干个棋子(不能平移),要求最后能移成黑白相间的一行棋子。如n=5时,成为:
○●○●○●○●○●
任务:编程打印出移动过程。
【输入】
输入n。
【输出】
移动过程。
【输入样例】
7
【输出样例】
step 0:ooooooo*******–
step 1:oooooo–o
step 2:oooooo*–o*
step 3:ooooo–oo
step 4:ooooo–oo
step 5:oooo–ooo
step 6:oooo***–ooo*
step 7:ooo–oooo*
step 8:oooo**–ooo*
step 9:o–o**ooooo*
step10:ooo*–oooo
step11:–ooooooo*
char c[N];
int n,blank,cnt;
void print(){
cout<<"step"<<fixed<<setw(2)<<cnt++<<":";
fer(i,0,2*n+2)cout<<c[i];
cout<<endl;
}
void mv(int k){
fer(j,0,2){
c[blank+j]=c[k+j];
c[k+j]='-';
}
blank=k;
print();
}
void solve(int n){
if(n==3){
mv(3);
mv(7);
mv(1);
mv(6);
mv(0);
}else{
mv(n);
mv(2*n);
solve(n-1);
}
}
signed main(){
cin>>n;
blank=2*n;
fer(i,0,n)c[i]='o';
fer(i,n,2*n)c[i]='*';
c[blank]='-';
c[blank+1]='-';
print();
solve(n-1);
return 0;
}
void hanoi(int n,char a,char b,char c){
if(n==1)cout<<1<<" "<<a<<" "<<b<<endl;
else{
hanoi(n-1,a,c,b);
cout<<n<<" "<<a<<" "<<b<<endl;
hanoi(n-1,c,b,a);
}
}
signed main(){
int n;cin>>n;
char a='A',b='B',c='C';
hanoi(n,a,b,c);
return 0;
}
设有n个选手进行循环比赛,其中n=2m,要求每名选手要与其他n-1名选手都赛一次,每名选手每天比赛一次,循环赛共进行n-1天,要求每天没有选手轮空。
输入
m(m<=10)
输出
表格形式的比赛安排表(数字之间以一个空格分开)
样例输入
3
样例输出
1 2 3 4 5 6 7 8
2 1 4 3 6 5 8 7
3 4 1 2 7 8 5 6
4 3 2 1 8 7 6 5
5 6 7 8 1 2 3 4
6 5 8 7 2 1 4 3
7 8 5 6 3 4 1 2
8 7 6 5 4 3 2 1
int a[N][N];
void solve(int a[N][N],int k,int n){
int m=1;
fer(s,1,k+1){//1~k
n=n/2;
fer(t,1,n+1){//1~n
fer(i,m+1,2*m+1){
fer(j,m+1,2*m+1){
a[i][j+(t-1)*m*2]=a[i-m][j+(t-1)*m*2-m];
a[i][j+(t-1)*m*2-m]=a[i-m][j+(t-1)*m*2];
}
}
}
m*=2;
}
}
signed main(){
int k;cin>>k;
int n=pow(2,k);
fer(i,1,n+1)a[1][i]=i;
solve(a,k,n);
fer(i,1,n+1){
fer(j,1,n+1){
cout<<fixed<<setw(3)<<a[i][j];
}
cout<<endl;
}
return 0;
}
#include
using namespace std;
const int N=1e6+10;
int q[N],tmp[N];
void merge_sort(int q[],int l,int r){ //归并排序
if(l>=r)return;
int mid=(l+r)>>1;
merge_sort(q,l,mid),merge_sort(q,mid+1,r); //先递归排序,后归并
int k=0,i=l,j=mid+1;//k是tmp数组的指针
while(i<=mid&&j<=r){
if(q[i]<=q[j])tmp[k++]=q[i++];//赋值的同时自增
else tmp[k++]=q[j++];
}
while(i<=mid)tmp[k++]=q[i++]; //把剩下的大数直接放进tmp数组里
while(j<=r)tmp[k++]=q[j++];
for(i=l,j=0;i<=r;i++,j++)q[i]=tmp[j];//把tmp数组里排好序的数放进q数组里
}
int main(){
int n;
cin>>n;
int i;
for(i=0;i<n;i++){
scanf("%d",&q[i]);
}
merge_sort(q,0,n-1);
for(i=0;i<n;i++){
printf("%d ",q[i]);
}
return 0;
}
基于归并排序
const int N=1e5+10;
int n;
int q[N],tmp[N];
typedef long long ll;
ll merge_sort(int q[],int l,int r){
if(l>=r)return 0;
int mid=(l+r)/2;
ll res=merge_sort(q,l,mid)+merge_sort(q,mid+1,r);
int k=0,i=l,j=mid+1;
while(i<=mid&&j<=r){
if(q[i]<=q[j])tmp[k++]=q[i++];
else {
tmp[k++]=q[j++];
res+=mid-i+1;
}
}
while(i<=mid)tmp[k++]=q[i++];
while(j<=r)tmp[k++]=q[j++];
for(i=l,j=0;i<=r;i++,j++){
q[i]=tmp[j];
}
return res;
}
int main(){
cin>>n;
for(int i=0;i<n;i++)scanf("%d",&q[i]);
cout<<merge_sort(q,0,n-1)<<endl;
return 0;
}
int a[N];
signed main(){
int n;cin>>n;
fer(i,0,n)cin>>a[i];
int x;cin>>x;
int l=0,r=n-1;
int res=-1;
while(l<=r){
int mid=(l+r)>>1;
if(a[mid]>x)r=mid-1;
else if(a[mid]==x){
res=mid;
r=mid-1;
}else l=mid+1;
}
if(res!=-1)cout<<res+1;
else cout<<res;
return 0;
}
signed main(){
int n,p;cin>>n>>p;
int res=n*(n+1)/2+1;
p-=2;
res-=p*(p+1)/2;
cout<<res;
return 0;
}