一、课堂作业
1.铺方砖
#include<iostream>
using namespace std;
int main()
{
int n,i,j,a[101];
cout<<"input n:";
cin>>n;
a[1]=1;a[2]=2;
cout<<"x[1]="<<a[1]<<endl;
cout<<"x[2]="<<a[2]<<endl;
for (i=3;i<=n;i++)
{
a[i]=a[i-1]+a[i-2];
cout<<"a["<<i<<"]="<<a[i]<<endl;
}
}
input n:10
x[1]=1
x[2]=2
a[3]=3
a[4]=5
a[5]=8
a[6]=13
a[7]=21
a[8]=34
a[9]=55
a[10]=89
2.整数划分
#include<iostream>
using namespace std;
int split(int n,int m)
{
if(n==1||m==1) return 1;
else if (n<m) return split(n,n);
else if(n==m) return split(n,n-1)+1;
else return split(n,m-1)+split(n-m,m);
}
int main()
{
int m,n;
cin>>m>>n;
cout<<split(m,n);
}
输入:
10
8
输出:
40
3.输油管道
#include <iostream>
#include <cmath>
using namespace std;
#define NUM 1001
int a[NUM];
int select(int left, int right, int k)
{
if (left >= right)
return a[left];
int i = left;
int j = right+1;
int pivot = a[left];
while (true)
{
do
{
i = i+1;
}
while (a[i] < pivot);
do
{
j = j-1;
}
while (a[j] > pivot);
if (i >= j)
break;
swap(a[i], a[j]);
}
if (j-left+1 == k)
return pivot;
a[left] = a[j];
a[j] = pivot;
if (j-left+1 < k)
return select(j+1, right, k-j+left-1);
else
return select(left, j-1, k);
}
int main()
{
int n;
int x;
int y;
cin>>n;
for (int i=0; i<n; i++)
cin>>x>>a[i];
y = select(0, n-1, n/2);
int min=0;
for(int i=0; i<n; i++)
min += (int)fabs(a[i]-y);
cout<<min<<endl;
return 0;
}
输入:
5
1 2
2 2
1 3
3 -2
3 3
输出:
6
4.最大子段和
#include<iostream>
using namespace std;
int MaxSum(int a[ ], int left, int right)
{
int sum=0;
if (left==right){
if (a[left]>0) sum=a[left];
else sum=0;
}
else
{
int center=(left+right)/2;
int leftsum=MaxSum(a, left, center);
int rightsum=MaxSum(a, center+1, right);
int s1=0; int lefts=0;
for (int i=center; i>=left; i--)
{
lefts+=a[i];
if (lefts>s1) s1=lefts;
}
int s2=0; int rights=0;
for (int j=center+1; j<=right; j++)
{
rights+=a[j];
if (rights>s2) s2=rights;
}
sum=s1+s2;
if (sum<leftsum) sum=leftsum;
if (sum<rightsum) sum=rightsum;
}
return sum;
}
int main()
{
int a[9]={-2,1,-3,4,-1,2,1,-5,4};
cout<<MaxSum(a,0,8);
}
数列−2, 1, −3, 4, −1, 2, 1, −5, 4,
其连续子数列中和最大的是4, −1, 2, 1,
其和为6
5.0-1背包动态规划问题
#include<bits/stdc++.h>
using namespace std;
#define NUM 50
#define CAP 1500
int v[NUM];
int w[NUM];
int p[NUM][CAP];
void knapsack(int c, int n)
{
int jMax=min(w[n]-1,c);
for( int j=0; j<=jMax; j++)
p[n][j]=0;
for( int j=w[n]; j<=c; j++)
p[n][j]=v[n];
for( int i=n-1; i>1; i--)
{
jMax=min(w[i]-1,c);
for( int j=0; j<=jMax; j++)
p[i][j]=p[i+1][j];
for(int j=w[i]; j<=c; j++)
p[i][j]=max(p[i+1][j], p[i+1][j-w[i]]+v[i]);
}
p[1][c]=p[2][c];
if (c>=w[1])
p[1][c]=max(p[1][c], p[2][c-w[1]]+v[1]);
}
void traceback( int c, int n, int x[ ])
{
for(int i=1; i<n; i++)
{
if (p[i][c]==p[i+1][c])
x[i]=0;
else
{
x[i]=1;
c-=w[i];
}
}
x[n]=(p[n][c])? 1:0;
}
int main ()
{
int x[NUM];
int W;
int n;
while (cin>>W && W)
{
cin>>n;
for (int i=1; i<=n; i++)
cin>>w[i]>>v[i];
memset (p, 0, sizeof(p));
knapsack(W, n);
cout<< p[1][W]<<endl;
traceback(W, n, x);
for (int i=1; i<=n; i++)
if (x[i])
cout<< i;
cout<<endl;
}
return 0;
}
6.8(n)皇后
#include<bits/stdc++.h>
using namespace std;
#define num 20
int n;
int x[num];
int sum;
bool Place(int t)
{
int i;
for (i=1; i<t; i++)
{
if ((abs(t-i) == abs(x[i]-x[t]))||(x[i] == x[t]))
return false;
}
return true;
}
void Backtrack(int t)
{
int i;
if (t>n)
{
sum++;
for (i=1;i<=n;i++)
{
cout<<x[i]<<" ";
cout<<endl;
}
}
else{
for (i=1; i<=n; i++)
{
x[t] = i;
if (Place(t)!=0) Backtrack(t+1);
}
}
}
int main()
{
Backtrack(8);
cout<<sum<<endl;
while (cin>>n)
{
sum = 0;
Backtrack(1);
cout<<"Total="<<sum<<endl;
}
return 0;
}
二、实验作业
1.杨辉三角形
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i,j,n,a[34][34];
cin>>n;
for (i=0;i<n;i++)
{
a[i][0]=1;
a[i][i]=1;
for (j=1;j<i;j++)
a[i][j]=a[i-1][j-1]+a[i-1][j];
}
for (i=0;i< n;i++)
{
for (j=0;j<=i;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
return 0;
}
输入:5
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
2.字符串对比
#include<bits/stdc++.h>
using namespace std;
int main()
{
int len1,len2;
char ch1[10],ch2[10];
cin>>ch1;
cin>>ch2;
len1=strlen(ch1);
len2=strlen(ch2);
if(len1==len2)
{
int flag=1;
for(int i=0;i<len1;i++)
if(ch1[i]!=ch2[i])
flag=0;
if(flag!=0)
cout<<"完全一致";
else
{
flag=1;
for(int i=0;i<len1;i++)
if(ch1[i]+32!=ch2[i]&&ch1[i]-32!=ch2[i]&&ch1[i]!=ch2[i])
flag=0;
if(flag!=0)
cout<<"长度相同,形式不同";
else cout<<"长度相同";
}
}
else cout<<"长度不同";
}
3.2n皇后问题
#include<bits/stdc++.h>
using namespace std;
int Sum(int*a,int*b,int*c,int m,int n)
{
int i,j,k;
int count=0;
if (m==n)return 1;
for (i = 0; i < n; i++)
{
if (a[m * n + i] == 0)
continue;
for (j=0;j<m;j++)
if (b[j]==i||b[j]-i==j-m||b[j]+j==i+m)
break;
if (j==m)
{
b[m] = i;
for (k=0;k<n;k++)
{
if (a[m*n+k]==0||k==i)
continue;
for (j=0;j<m;j++)
if (c[j]==k||c[j]-k==j -m||c[j]+j==k+m)
break;
if (j == m)
{
c[m] = k;
count+=Sum(a,b,c,m+1,n);
}
}
}
}
return count;
}
int main()
{
int a[64], b[8], c[8], i, j, n;
cin>>n;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
cin>>a[i*n+j];
cout<<Sum(a,b,c,0,n);
return 0;
}
输入:5
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
输出:40
4.拦截导弹
#include<bits/stdc++.h>
using namespace std;
int v[10000],f[10000],g[10000]={0,1},Max,Min;
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>v[i];
f[i]=g[i]=1;
for(int j=1;j<i;j++)
{
if(v[i]<=v[j])
{
f[i]=max(f[i],f[j]+1);
}
if(v[i]>v[j])
{
g[i]=max(g[i],g[j]+1);
}
}
if(f[i]>Max)
{
Max=f[i];
}
if(g[i]>Min)
{
Min=g[i];
}
}
cout<<Max<<" "<<Min;
return 0;
}
5.Fibonacc数列
#include<iostream>
using namespace std;
int Fbi(int i)
{
if (i<2)
{
return i=1;
}
return Fbi(i-1)+Fbi(i-2);
}
int main()
{
int n,x;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x;
cout<<Fbi(x-1)<<endl;
cout<<Fbi(x-1)%10007<<endl;
}
}
6.分解质因数
#include<stdio.h>
#include<iostream>
using namespace std;
int main()
{
int a,b,i,d,c,j;
cin>>a>>b;
if(a<=b&&a>=2&&a<=10000&&b<=10000)
{
for(i=a;i<=b;i++)
{
d=1;
for(j=2;j<i;j++)
if(i%j==0)
{
d=0;
break;
}
if(d==1)
cout<<i<<"="<<i<<endl;
else if(d==0)
{
cout<<i<<"=";
j=2;
c=i;
while(1)
{
while(c%j==0)
{
cout<<j;
c=c/j;
if(c!=1)
cout<<"*";
}
if(c==1)
{
cout<<endl;
break;
}
j++;
}
}
}
}
return 0;
}
7.校门外的树
#include<cstdio>
#include<iostream>
using namespace std;
int s[10010],mark[10010],l,m,a,b,now,ans;
int main()
{
cin>>l>>m;
for(int i=1;i<=m;i++)
{
cin>>a>>b;
s[a]=max(s[a],b-a+1);
}
ans=l+1;
for(int i=0;i<=l+1;i++)
{
now=max(now,s[i]);
if(now)
ans--;
now--;
}
cout<<ans;
return 0;
}
8.夺宝奇兵
#include <iostream>
using namespace std;
const int Max=1000;
int a[Max][Max],d[Max][Max];
int main()
{
int n;
cin>> n;
for(int i = 0; i < n; i++)
for(int j = 0; j <= i; j++)
cin>> a[i][j];
for(int i = n-1; i >= 0; i--)
for(int j = 0; j <= i; j++)
d[i][j] = max(d[i+1][j], d[i+1][j+1])+a[i][j];
cout<<d[0][0]<< " ";
return 0;
}
输入:5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出:30