算法与分析.docx
《算法与分析.docx》由会员分享,可在线阅读,更多相关《算法与分析.docx(14页珍藏版)》请在冰豆网上搜索。
![算法与分析.docx](https://file1.bdocx.com/fileroot1/2023-1/29/d7b5f658-32b7-458a-8029-836a6a8274fc/d7b5f658-32b7-458a-8029-836a6a8274fc1.gif)
算法与分析
第六页1-1统计数字问题:
#include
usingnamespacestd;
ints[10]; //记录0~9出现的次数
inta[10]; //a[i]记录n位数的规律
voidsum(intn,intl,intm)
{
//去除前缀0
if(m==1){
intzero=1;
for(inti=0;i<=l;i++){
s[0]-=zero;
zero*=10;
}
}
//位数为1位时,出现次数加1
if(n<10){
for(inti=0;i<=n;i++){
s[i]+=1;
}
return;
}
//位数大于1时的出现次数
//计算规律f(n)=n*10^(n-1)
for(intt=1;t<=l;t++){
m=1;
for(inti=1;i a[t]=t*m;
}
//求出输入数为10的n次方
intzero=1;
for(inti=0;i zero*=10;
}
//求出最高位以后的数
intyushu=n%zero;
//求出最高位zuigao
intzuigao=n/zero;
//求出0~zuigao-1位的数的出现次数
for(i=0;i s[i]+=zero;
}
//求出与余数位数相同的0~zuigao-1位中0~9出现的次数
for(i=0;i<10;i++){
s[i]+=zuigao*a[l];
}
//如果余数是0,则程序可结束,不为0则补上所缺的0数,和最高位对应所缺的数
//补上所缺的0数,并且最高位加1
if(yushu==0)
{
s[zuigao]++;
s[0]+=l;
}
else
{
inti=0;
while((zero/=10)>yushu)
{
i++;
}
s[0]+=i*(yushu+1);//补回因作模操作丢失的0
s[zuigao]+=(yushu+1);//补回最高位丢失的数目
sum(yushu,l-i-1,m+1);//处理余位数
}
}
intmain()
{
inti,m,n,N,l;
cout<<"输入页码数:
";
cin>>N;
cout<<'\n';
n=N;
//求出N的位数i+1
for(i=0;n>=10;i++)
{
n/=10;
}
l=i;
//cout<<"位数:
"< sum(N,l,1);
for(i=0;i<10;i++)
{
cout<<"数字"<
"<
}
system("pause");
return0;
}
1-2字典序问题
#include
usingnamespacestd;
#include
//计算以i开始的长度为k的所有数的个数,前提是升序
intf(inti,intk)
{
intj;
intsum=0;
if(k==1)return1;
else
{
for(j=i+1;j<=26;j++)
{
sum+=f(j,k-1);
}
}
returnsum;
}
//计算长度为k的所有组合的个数,前提是升序
intg(intk)
{
inti,sum;
sum=0;
for(i=1;i<=26;i++)
sum+=f(i,k);
returnsum;
}
//转换成数字
intchange(charc)
{
returnc-'a'+1;
}
//给出一个字符串返回一个序号
intorder(strings)
{
intk,i,j;
intsum=0,temp=0;
k=s.size();
//获取1~k-1长度的子字符串数
for(i=1;i sum+=g(i);
//小于第一个字母的长度为k的所有组合个数
for(i=1;i sum+=f(i,k);
//以第一个字母作为开始的字符串组合个数
for(i=1,temp=change(s[0]);i{
intt=change(s[i]);//获取此时的字母并转化成数字
intlen=s.size()-i; //获取此时的长度
for(j=temp+1;j sum+=f(j,len);
temp=t; ////获取当前字符值,方便下一次从此项+1项开始累加
}
returnsum+1;
}
intmain()
{
strings;
while(cin>>s)
{
cout<}
return0;
}
//总结:
本程序最难的就是对每一位的字符计算以小于其的字符开头
//但大于前面字符的的所有字符串个数,所以通过从前一项加1到比本项小的所有头
//,带着当前长度累加。
还不能遗漏最后加1,获取当前位。
//还要注意读取字符串的首位并不是高位,需要转换。
贪心算法,会场安排问题:
4-1128页
#include
#include
#include
#include
usingnamespacestd;
typedefstructconference
{
intstart_time;
intfinish_time;
boolflag;
}CONFERENCE;
boolcmp(CONFERENCEA,CONFERENCEB)
{
returnA.start_time}
intmain(intargc,_TCHAR*argv[])
{
intk,sum=0;
vectorv;
CONFERENCEcon;
ifstreamfin("input.txt");
ofstreamfout("output.txt");
fin>>k;
for(inti=0;i {
fin>>con.start_time>>con.finish_time;
con.flag=false;
v.push_back(con);
}
sort(v.begin(),v.end(),cmp);
for(inti=0;i {
if(!
v[i].flag)
{
sum+=1;
v[i].flag=true;
intm=i;
for(intj=m;j {
if(v[m].finish_time<=v[j+1].start_time)
{
v[j+1].flag=true;
m=j+1;
}
}
}
}
fout< fin.close();
fout.close();
return0;
}
贪心算法,磁盘文件最优存储问题:
4-4
#include
#include
int cmp (const void *a , const void *b)
{
return *(double *)a - *(double *)b;
}
double greedy(double a[],int n)
{
qsort(a,n,sizeof(double),cmp);
int mid = (n - 1) / 2;
double x[n];
x[mid] = a[n-1];
for(int i = mid+1;i < n;i++)
x[i] = a[n - 2*(i-mid)];
for(int i = mid-1;i >= 0;i--)
x[i] = a[n - 2*(mid-i) - 1];
double sum = 0,exp = 0;
for(int i = 0;i < n;i++)
{
sum += a[i];
for(int j = i+1;j < n;j++)
exp += x[i]*x[j]*(j-i);
}
return exp/sum/sum;
}
int main() {
int i,j,n;
double a[1000],exp;
scanf("%d",&n);
for(i = 0;i < n;i++)
scanf("%lf",&a[i]);
exp = greedy(a,n);
printf("%lf\n",exp);
}
贪心算法,多次最优服务次序问题:
4-7
#include
#include
#include
usingnamespacestd;
intn ,i;
doublegreedy(vectorx)
{
intn=x.size();
sort(x.begin(),x.end());
for(i=1;i x[i]+=x[i-1];
doublet=0;
for(i=0;i t+=x[i];
t/=n;
returnt;
}
intmain()
{
inta[1000];
cin>>n;
vectorx;
for(i=0;i {
cin >>a[i];
x.push_back(a[i]);
}
printf("%.2f\n",greedy(x));
//system("pause");
return0;
}
方法二:
贪心算法,最优服务次序问题:
4-6
#include
#include
#include
#include
usingnamespacestd;
int*wtim=newint[999];
intdtgh(int*p,intmaxk)
{
for(intj=0;j{
wtim[j]=0;
}
for(inti=0;i{
if(i==0)
{
wtim[i]=p[0];
}
else
{
wtim[i]=wtim[i-1]+p[i];
}
}
return0;
}
intmain()
{
intn;
while(cin>>n)
{
int*p=newint[n];
for(intx=0;x {
cin>>p[x];
}
cout< sort(p,p+n);
doublesum=0.00;
dtgh(p,n);
for(intl=0;l {
sum=sum+wtim[l];
}
printf("%.2f",sum/n);
}
return0;
}
第二章:
众数问题
方法一:
#include
intmain()
{
longs[50000];
longx[50000],y[50000];
longn,m,max,l,i,j;
scanf("%ld",&n);
scanf("%ld",&s[0]);
x[0]=s[0];
y[0]=1;
m=1;
for(i=1;i{
scanf("%ld",&s[i]);
for(j=0;jif(s[i]==x[j])
{
y[j]++;
break;
}
if(j==m)
{
x[m]=s[i];
y[m]=1;
m++;
}
}
max=y[0];
l=x[0];
for(i=1;i{
if(y[i]>max)
{
max=y[i];
l=x[i];
}
if(y[i]==max&&x[i]l=x[i];
}
printf("%ld\n%ld",l,max);
return0;
}
方法二:
#include
#defineSIZE100
voiddata_output(inta[],intn);
voiddata_input(inta[],intn);
voiddata_sort(inta[],intn);
intdata_find(inta[],intn);
intmain()
{
intarr[SIZE];
intindex;
intn;
printf("输入集合元素个数(0~%d):
\n",SIZE);
scanf("%d",&n);
data_input(arr,n);
data_output(arr,n);
data_sort(arr,n);
index=data_find(arr,n);
printf("众数:
%d\n重数:
%d\n",arr[index],index);
return0;
}
voiddata_input(inta[],intn)
{
inti;
printf("输入%d个数据:
\n",n);
for(i=0;iscanf("%d",&a[i]);
}
voiddata_output(inta[],intn)
{
inti;
printf("集合元素为:
\n");
for(i=0;iprintf("%d",a[i]);
printf("\n");
}
voiddata_sort(inta[],intn)
{
inti;
intj;
intk;
inttemp;
for(i=0;i{
k=i;
for(j=i+1;jif(a[k]>a[j])
k=j;
if(k!
=i)
{
temp=a[i];
a[i]=a[k];
a[k]=temp;
}
}
}
intdata_find(inta[],intn)
{
intcount;
inttemp;
inti;
count=1;
temp=1;
for(i=0;i{
if(a[i]==a[i+1])
temp++;
else
{
if(temp>count)
{
count=temp;
temp=1;
}
}
}
returncount;
}