一本通网站练习目录及AC代码(基础篇己完结)
信息学奥赛一本通
第一部分:C++语言
第一章 C++语言入门
1000:入门测试题目
#include<iostream> using namespace std; int main() { int a,b; cin>>a>>b; cout<<a+b; return 0; }
1001:Hello,World!
#include<iostream> using namespace std; int main() { cout<<"Hello,World!"; return 0; }
1002:输出第二个整数
#include<iostream> using namespace std; int main() { int a,b,c; cin>>a>>b>>c; cout<<b; return 0; }
1003:对齐输出
#include<iostream> #include<bits/stdc++.h> using namespace std; int main() { int a,b,c; cin>>a>>b>>c; cout<<fixed<<setw(8)<<a<<' '; cout<<fixed<<setw(8)<<b<<' '; cout<<fixed<<setw(8)<<c; return 0; }
1004:字符三角形
#include<iostream> using namespace std; int main() { char ch; cin>>ch; cout<<" "<<ch<<'\n'; cout<<" "<<ch<<ch<<ch<<'\n'; cout<<ch<<ch<<ch<<ch<<ch<<'\n'; return 0; }
1005:地球人口承载力估计
#include<cstdio> int main(){ int a,b,x,y; double z; scanf("%d %d %d %d",&x,&a,&y,&b); z=(a*x-b*y)/(a-b); printf("%.2f",z); return 0; }
第二章 顺序结构程序设计
第一节 运算符和表达式
1006:A+B问题
#include<iostream> using namespace std; int main() { int a,b; cin>>a>>b; cout<<a+b; return 0; }
1007:计算(a+b)×c的值
#include<iostream> using namespace std; int main(){ int a,b,c; cin>>a>>b>>c; cout<<(a+b)*c<<endl; return 0; }
1008:计算(a+b)/c的值
#include<iostream> using namespace std; int main() { int a,b,c; cin>>a>>b>>c; cout<<(a+b)/c; return 0; }
1009:带余除法
#include<iostream> using namespace std; int main() { int bcs,cs,s,ys; cin>>bcs>>cs; s=bcs/cs; ys=bcs%cs; cout<<s<<' '<<ys; return 0; }
1010:计算分数的浮点数值
#include<iostream> #include<iomanip> using namespace std; int main() { double a,b; cin>>a>>b; cout<<fixed<<setprecision(9)<<a/b; return 0; }
第二节 常量和变量
1011:甲流疫情死亡率
#include<iostream> #include<iomanip> using namespace std; int main(){ int a,b; cin>>a>>b; cout<<fixed<<setprecision(3)<<100.0*b/a<<'%'<<endl; return 0; }
1012:计算多项式的值
#include<iostream> #include<iomanip> using namespace std; int main(){ double x,a,b,c,d; cin>>x>>a>>b>>c>>d; cout<<fixed<<setprecision(7)<<x*(x*(a*x+b)+c)+d; return 0; }
1013:温度表达转化
#include<iostream> #include<iomanip> using namespace std; int main(){ double f; cin>>f; cout<<fixed<<setprecision(5)<<(f-32)/9*5; return 0; }
1014:与圆相关的计算
#include<iostream> using namespace std; #include<iomanip> int main() { double r,pi=3.14159,d,c,s; cin>>r; d=r*2; c=pi*2*r; s=pi*r*r; cout<<fixed<<setprecision(4)<<d; cout<<' '<<fixed<<setprecision(4)<<c; cout<<' '<<fixed<<setprecision(4)<<s; return 0; }
1015:计算并联电阻的阻值
#include<iostream> using namespace std; #include<iomanip> // int main(){ float r1,r2; cin>>r1>>r2; cout<<fixed<<setprecision(2)<<r1*r2/(r1+r2); return 0; }
第三节 标准数据类型
1016:整型数据类型存储空间大小
#include<iostream> using namespace std; //#include<iomanip> fixed<<setprecision int main(){ cout<<sizeof(int)<<' '<<sizeof(short)<<endl; return 0; }
1017:浮点型数据类型存储空间大小
#include<iostream> using namespace std; //#include<iomanip> fixed<<setprecision int main(){ cout<<sizeof(float)<<' '<<sizeof(double)<<endl; return 0; }
1018:其他数据类型存储空间大小
#include<iostream> using namespace std; //#include<iomanip> fixed<<setprecision int main(){ cout<<sizeof(bool)<<' '<<sizeof(char)<<endl; return 0; }
1019:浮点数向零舍入
#include<iostream> using namespace std; //#include<iomanip> fixed<<setprecision int main(){ float a; int b; cin>>a; b=int(a); cout<<b<<endl; return 0; }
1020:打印ASCII码
#include<iostream> using namespace std; //#include<iomanip> fixed<<setprecision int main(){ char ch; cin>>ch; cout<<ch+0<<endl; return 0; }
1021:打印字符
#include<iostream> using namespace std; //#include<iomanip> fixed<<setprecision int main(){ int n; cin>>n; cout<<char(n)<<endl; return 0; }
1022:整型与布尔型的转换
#include<iostream> using namespace std; int main(){ int n; bool bl; cin>>n; bl=bool(n); n=bl; cout<<n<<endl; return 0; }
1023:Hello,World!的大小
#include<iostream> using namespace std; int main(){ cout<<sizeof("Hello, World!"); return 0; }
第四节 数据输入输出
1024:保留3位小数的浮点数
#include<iostream> #include<iomanip> using namespace std; int main(){ float a; cin>>a; cout<<fixed<<setprecision(3)<<a<<endl; return 0; }
1025:保留12位小数的浮点数
#include<iostream> #include<iomanip> using namespace std; int main(){ double a; cin>>a; cout<<fixed<<setprecision(12)<<a<<endl; return 0; }
1026:空格分隔输出
#include<iostream> #include<iomanip> using namespace std; int main(){ char a; int b; float c; double d; cin>>a>>b>>c>>d; cout<<a<<' '<<b<<' '<<fixed<<setprecision(6)<<c<<' '<<d<<endl; return 0; }
1027:输出浮点数
#include<cstdio> using namespace std; int main(){ double a; scanf("%lf",&a); printf("%lf\n%.5lf\n%e\n%g",a,a,a,a); return 0; }
1028:字符菱形
#include<iostream> using namespace std; int main(){ int flag=0,m=3; char ch; cin>>ch; for(int i=1;i<=2*m-1;i++) { int tmpi=i>m?2*m-i:i; for(int j=1;j<m+1-tmpi;j++) cout<<' '; for(int j=1;j<=2*tmpi-1;j++) cout<<ch; cout<<'\n'; } return 0; }
第五节 顺序结构实例
1029:计算浮点数相除的余
#include<iostream> using namespace std; #include<cmath> int main() { double a,b; cin>>a>>b; int k=floor(a/b); cout<<a-k*b; return 0; }
1030:计算球的体积
#include<iostream> #include<iomanip> using namespace std; const double pi=3.14; int main(){ double r; cin>>r; cout<<fixed<<setprecision(2)<<4*pi/3*r*r*r<<endl; return 0; }
1031:反向输出一个三位数
#include<iostream> using namespace std; int main(){ int a; cin>>a; do { cout<<a%10; a/=10; }while(a); return 0; }
1032:大象喝水查
#include<iostream> using namespace std; const double pi=3.14159; int main(){ int h,r; cin>>h>>r; cout<<int(20000/(pi*r*r*h))+1; return 0; }
1033:计算线段长度
#include<iostream> #include<cmath> #include<iomanip> using namespace std; int main(){ double xa,ya,xb,yb; cin>>xa>>ya>>xb>>yb; cout<< fixed<<setprecision(3)<<sqrt((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb)); return 0; }
1034:计算三角形面积
#include<iostream> #include<cmath> #include<iomanip> using namespace std; double jl(double x1,double y1,double x2,double y2) { return sqrt((x1-x2)*(x1-x2)+(y2-y1)*(y2-y1)); } int main(){ double x1,y1,x2,y2,x3,y3,p,a,b,c,s; cin>>x1>>y1>>x2>>y2>>x3>>y3; a=jl(x1,y1,x2,y2); b=jl(x2,y2,x3,y3); c=jl(x1,y1,x3,y3); p=(a+b+c)/2; s=sqrt(p*(p-a)*(p-b)*(p-c)); cout<<fixed<<setprecision(2)<<s<<endl; return 0; }
1035:等差数列末项计算
#include<iostream> using namespace std; int main(){ int a1,a2,n; cin>>a1>>a2>>n; cout<<a1+(n-1)*(a2-a1); return 0; }
1036:A×B问题
#include<iostream> using namespace std; #include<cmath> int main() { int a,b; cin>>a>>b; cout<<1ll*a*b; return 0; }
1037:计算2的幂
#include<iostream> using namespace std; int main(){ int n; cin>>n; long long m=1; for(int i=1;i<=n;i++)m*=2; cout<<m<<endl; return 0; }
1038:苹果和虫子
#include<iostream> using namespace std; int main(){ int n,x,y,m; cin>>n>>x>>y; m=n-1.0*y/x; if(m<0)m=0; cout<<m<<endl; return 0; }
第三章 程序的控制结构
第一节 if选择结构
1039:判断数正负
#include<iostream> using namespace std; int main(){ int n; cin>>n; if(n>0)cout<<"positive"; else cout<<(n==0?"zero":"negative")<<endl; return 0; }
1040:输出绝对值
#include<iostream> #include<iomanip> using namespace std; int main(){ double a; cin>>a; cout<<fixed<<setprecision(2)<<(a>0?a:a*(-1)); return 0; }
1041:奇偶数判断
#include<iostream> using namespace std; int main(){ long a; cin>>a; cout<<(a%2?"odd":"even"); return 0; }
1042:奇偶ASCII值判断
#include<cstdio> int main() { if(getchar()%2)printf("YES"); else printf("NO"); return 0; }
1043:整数大小比较
#include<iostream> using namespace std; int main(){ long long a,b; cin>>a>>b; if(a>b)cout<<'>'; else cout<<(a==b?'=':'<'); return 0; }
1044:判断是否为两位数
#include<iostream> using namespace std; int main(){ short n; cin>>n; if(n>=10&&n<=99)cout<<1; else cout<<0; return 0; }
1045:收集瓶盖赢大奖
#include<iostream> using namespace std; int main(){ double a,b; cin>>a>>b; if(a>=10||b>=20)cout<<1; else cout<<0; return 0; }
1046:判断一个数能否同时被3和5整除
#include<iostream> using namespace std; int main(){ long long n; cin>>n; if(n%3==0&&n%5==0)cout<<"YES"; else cout<<"NO"; return 0; }
1047:判断能否被3,5,7整除
#include<iostream> using namespace std; int main(){ long long n; cin>>n; if(n%3==0&&n%5==0)cout<<"YES"; else cout<<"NO"; return 0; }
1048:有一门课不及格的学生
#include<iostream> using namespace std; int main(){ long long n; cin>>n; if(n%3==0&&n%5==0)cout<<"YES"; else cout<<"NO"; return 0; }
第二节 switch语句
1049:晶晶赴约会
#include<iostream> using namespace std; int main() { int n; cin>>n; if(n==1||n==3||n==5)cout<<"NO"; else cout<<"YES"; return 0; }
1050:骑车与走路
#include<iostream> using namespace std; int main(){ double x,b,w; cin>>x; b=27+23+x/3; w=x/1.2; if(w>b)cout<<"Bike"; else cout<<(w==b?"All":"Walk"); return 0; }
1051:分段函数
#include<iostream> #include<iomanip> using namespace std; int main(){ float x,y; cin>>x; if(x<5)y=2.5-x; else if(x>=10)y=x/2-1.5; else y=2-1.5*(x-3)*(x-3); cout<<fixed<<setprecision(3)<<y; return 0; }
1052:计算邮资
#include<iostream> using namespace std; int main(){ int n,p; char a; cin>>n>>a; p=n>1000?(8+(n-1000+499)/500*4):8; p+=(a=='y'?5:0); cout<<p; return 0; }
1053:最大数输出
#include<iostream> using namespace std; int main(){ int a,b,c,maxn; cin>>a>>b>>c; maxn=a; if(maxn<b)maxn=b; if(maxn<c)maxn=c; cout<<maxn; return 0; }
1054:三角形判断
#include<iostream> using namespace std; int main(){ int a,b,c; cin>>a>>b>>c; if(a+b>c&&a+c>b&&b+c>a)cout<<"yes"; else cout<<"no"; return 0; }
1055:判断闰年
#include<iostream> using namespace std; int main(){ int n; cin>>n; cout<<(n%100==0&&n%400!=0||n%4!=0?'N':'Y'); return 0; }
1056:点和正方形的关系
#include<iostream> using namespace std; int main(){ long long x,y; cin>>x>>y; if((-1<=x)&&(x<=1)&&(-1<=y)&&(y<=1))cout<<"yes"; else cout<<"no"; return 0; }
1057:简单计算器
#include<iostream> using namespace std; int main(){ int a,b; char c; cin>>a>>b>>c; switch(c) { case '+':cout<<a+b;break; case '-':cout<<a-b;break; case '*':cout<<a*b;break; case '/': if(b==0)cout<<"Divided by zero!"; else cout<<a/b;break; default:cout<<"Invalid operator!"; } return 0; }
1058:求一元二次方程
#include<iostream> #include<cmath> #include<iomanip> using namespace std; int main() { double a,b,c; cin>>a>>b>>c; double det; det=b*b-4*a*c; if(det<-1e-12) { cout<<"No answer!"; } else { if(fabs(det)<1e-12) { cout<<"x1=x2="<<fixed<<setprecision(5)<<-b/(2*a); } else { double x1,x2; x1=(-b+sqrt(det))/2/a; x2=(-b-sqrt(det))/2/a; if(x1<x2) { cout<<"x1="<<fixed<<setprecision(5)<<x1<<";x2="<<fixed<<setprecision(5)<<x2; } else { cout<<"x1="<<fixed<<setprecision(5)<<x2<<";x2="<<fixed<<setprecision(5)<<x1; } } } return 0; }
第四章 循环结构的程序设计
第一节 for语句
1059:求平均年龄
#include<iostream> #include<iomanip> using namespace std; int main(){ int n,b[1000],sum=0; cin>>n; for(int i=1;i<=n;i++) { cin>>b[i]; sum+=b[i]; } cout<<fixed<<setprecision(2)<<1.0*sum/n; return 0; }
1060:均值
#include<iostream> #include<iomanip> using namespace std; int main(){ int n; cin>>n; double a[1000],sum=0; for(int i=1;i<=n;i++) { cin>>a[i]; sum+=a[i]; } cout<<fixed<<setprecision(4)<<sum/n; return 0; }
1061:求整数的和与均值
#include<iostream> #include<iomanip> using namespace std; int main(){ int n,a[10001],sum=0; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; sum+=a[i]; } cout<<sum<<' '<<fixed<<setprecision(5)<<1.0*sum/n; return 0; }
1062:最高的分数
#include<iostream> using namespace std; int main(){ int n,a[1000],maxn=-1; cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; if(a[i]>maxn)maxn=a[i]; } cout<<maxn; return 0; }
1063:最大跨度值
#include<iostream> using namespace std; int main(){ int n,a[1001],maxn=-1,minn=1001; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; if(minn>a[i])minn=a[i]; if(maxn<a[i])maxn=a[i]; } cout<<maxn-minn; return 0; }
1064:奥运奖牌计数
#include<iostream> using namespace std; int main(){ int n,a,b,c,suma=0,sumb=0,sumc=0,sum; cin>>n; for(int i=1;i<=n;i++) { cin>>a>>b>>c; suma+=a,sumb+=b,sumc+=c; } sum=suma+sumb+sumc; cout<<suma<<' '<<sumb<<' '<<sumc<<' '<<sum; return 0; }
1065:奇数求和
#include<iostream> using namespace std; int main(){ int m,n,sum=0; cin>>m>>n; for(int i=m;i<=n;i++) if(i%2)sum+=i; cout<<sum; return 0; }
1066:满足条件的数累加
#include<iostream> using namespace std; int main(){ int m,n,sum=0; cin>>m>>n; for(int i=m;i<=n;i++) if(!(i%17))sum+=i; cout<<sum; return 0; }
1067:整数的个数
#include<iostream> using namespace std; int main(){ int n,m,sum1=0,sum5=0,sum10=0; cin>>n; for(int i=1;i<=n;i++) { cin>>m; if(m==1)sum1++; if(m==5)sum5++; if(m==10)sum10++; } cout<<sum1<<'\n'<<sum5<<'\n'<<sum10; return 0; }
1068:与指定数字相同的数的个数
#include<iostream> using namespace std; int main(){ int n,x,m,sum=0; cin>>n>>m; for(int i=1;i<=n;i++) { cin>>x; if(x==m)sum++; } cout<<sum; return 0; }
1069:乘方计算
#include<iostream> using namespace std; int main(){ int a,n,ans=1; cin>>a>>n; for(int i=1;i<=n;i++) ans*=a; cout<<ans; return 0; }
1070:人口增长
#include<iostream> #include<iomanip> using namespace std; int main(){ double a,n,ans=1; cin>>a>>n; for(int i=1;i<=n;i++) ans*=1.001; cout<<fixed<<setprecision(4)<<ans*a; return 0; }
1071:菲波那契数
#include<iostream> using namespace std; int main(){ int k,a[50]; cin>>k; a[1]=1,a[2]=1; for(int i=3;i<=k;i++) a[i]=a[i-1]+a[i-2]; cout<<a[k]; return 0; }
1072:鸡尾酒疗法
#include<iostream> #include<cmath> #include<cstdio> using namespace std; int main() { int n; double z,y,z1,y1,jd=1e-6; double new1,old; cin>>n; cin>>z>>y; old=y/z; //这个计算要放在循环外面才行 for(int i=0;i<n-1;i++) { cin>>z1>>y1; new1=y1/z1; old=y/z; //这个计算要放在循环外面才行 if(new1-old>0.05-jd) cout<<"better"<<endl; else if((old-new1)>0.05-jd) cout<<"worse"<<endl; else cout<<"same"<<endl; } return 0; }
1073:救援
#include<iostream> #include<cmath> using namespace std; int main(){ double n,a,b,c,sum=0; int s; cin>>n; for(int i=1;i<=n;i++) { cin>>a>>b>>c; sum+=sqrt(a*a+b*b)/25+1.5*c; } s=ceil(sum); cout<<s; return 0; }
1074:津津的储蓄计划
#include<iostream> using namespace std; int main(){ int a[13],b=0,sum=0,i; for(i=1;i<=12;i++)cin>>a[i]; for(i=1;i<=12;i++) { b+=300-a[i]; if(b<0)break; sum+=b/100*100; b%=100; } if(i==13)cout<<1.2*sum+b; else cout<<-i; return 0; }
1075:药房管理
#include<iostream> using namespace std; int main(){ int n,m,a,ans=0; cin>>n>>m; for(int i=1;i<=m;i++) { cin>>a; if(n>=a)n-=a; else ans++; } cout<<ans; return 0; }
1076:正常血压
#include<iostream> using namespace std; int main(){ int n,a,b,ans=0,maxn=-1; cin>>n; for(int i=1;i<=n;i++) { cin>>a>>b; if(90<=a&&a<=140&&60<=b&&b<=90){ ans++; if(ans>maxn)maxn=ans; } else ans=0; } cout<<maxn; return 0; }
1077:统计满足条件的4位数
#include<iostream> using namespace std; int main(){ int n,a,a1,a2,a3,a4,ans=0; cin>>n; for(int i=1;i<=n;i++) { cin>>a; a1=a%10; a2=a/10%10; a3=a/100%10; a4=a/1000; if(a1>a2+a3+a4)ans++; } cout<<ans; return 0; }
1078:求分数序列和
#include<iostream> #include<iomanip> using namespace std; int main(){ float n,p,q,tmp,ans=0; p=1,q=2,ans=q/p; cin>>n; for(int i=2;i<=n;i++) { tmp=q; q+=p; p=tmp; ans+=q/p; } cout<<fixed<<setprecision(4)<<ans; return 0; }
1079:计算分数加减表达式的值
#include<iostream> #include<iomanip> using namespace std; int main(){ int n; double s; cin>>n; for(int i=1;i<=n;i++) s+=(i%2?1.0/i:-1.0/i); cout<<fixed<<setprecision(4)<<s; return 0; }
1080:余数相同问题
#include<iostream> using namespace std; int main(){ int a,b,c,ans; cin>>a>>b>>c; for(int i=2;i<=a||a<=b||a<=c;i++) if(a%i==b%i&&a%i==c%i) { ans=i; break; } cout<<ans; return 0; }
1081:分苹果
#include<iostream> using namespace std; int main(){ int n; cin>>n; cout<<n*(n+1)/2; return 0; }
1082:求小数的某一位
#include<iostream> using namespace std; int main(){ int a,b,c,ans; cin>>a>>b>>c; a%=b; for(int i=1;i<=c;i++) { ans=a*10/b; a=a*10%b; } cout<<ans; return 0; }
1083:计算星期几
#include<iostream> #include<cmath> #include<cstdio> using namespace std; int main() { int a,b,xh=0,sum=1;//循环 int yx;//有效的次方 cin>>a>>b; a%=7; for(int i=1;i<=b;i++) { sum=sum*a; if((sum%7==a)&&i>1) { xh=i-1; break; } } if(xh>1) { yx=int(pow(a,b%xh))%7; } else { yx=sum%7; } switch(yx) { case 1:cout<<"Monday";break; case 2:cout<<"Tuesday";break; case 3:cout<<"Wednesday";break; case 4:cout<<"Thursday";break; case 5:cout<<"Friday";break; case 6:cout<<"Saturday";break; case 0:cout<<"Sunday";break; } return 0; }
#include<iostream> #include<iomanip> using namespace std; int main(){ int a,b,ans; cin>>a>>b; ans=a%1000; for(int i=1;i<b;i++) ans=ans*a%1000; cout<<setfill('0')<<setw(3)<<ans; return 0; }
第二节 while语句
1085:球弹跳高度的计算
#include<iostream> using namespace std; int main(){ double h0,n=10,s,h; cin>>h0; s=-h0,h=h0; for(int i=1;i<=n;i++) { s+=h*2; h/=2; } cout<<s<<'\n'<<h; return 0; }
1086:角谷猜想
#include<iostream> using namespace std; int main(){ int n; cin>>n; while(n!=1){ if(n%2){ cout<<n<<"*3+1="; n=n*3+1; cout<<n<<'\n'; } else { cout<<n<<'/'<<2<<'='; n/=2; cout<<n<<'\n'; } } cout<<"End"; return 0; }
1087:级数求和
#include<iostream> using namespace std; int main(){ double k,ans=0; long long n=1; cin>>k; while(ans<=k+(1e-16)) { ans+=1.0/n++; } cout<<n-1; return 0; }
1088:分离整数的各个数
#include<iostream> using namespace std; int main(){ int n; cin>>n; cout<<n%10; n/=10; while(n) { cout<<' '<<n%10; n/=10; } return 0; }
1089:数字反转
#include<iostream> using namespace std; int main(){//余数自带符号,如(-31)%10=-1 int n,ans=0; cin>>n; while(n) { ans=ans*10+n%10; n/=10; } cout<<ans; return 0; }
1090:含k个3的数
#include<iostream> using namespace std; int main(){ int n,k,ans=0; cin>>n>>k; if(n%19) cout<<"NO"; else { while(n) { if(n%10==3)ans++; n/=10; } if(ans==k)cout<<"YES"; else cout<<"NO"; } return 0; }
第三节 do-while语句
1085:球弹跳高度的计算
//1085:球弹跳高度的计算 #include<iostream> using namespace std; int main(){ double h,ans,i; cin>>h; ans=-h; i=0; do { ans+=h*2; h/=2; i++; }while(i<10); cout<<ans<<endl<<h; return 0; }
1086:角谷猜想
//1086:角谷猜想 #include<iostream> using namespace std; int main(){ int n; cin>>n; do { cout<<n; if(n%2) { cout<<"*3+1="; n=n*3+1; } else { cout<<"/2="; n/=2; } cout<<n<<endl; }while(n!=1); cout<<"End"<<endl; return 0; }
1087:级数求和
//1087:级数求和 #include<iostream> using namespace std; int main(){ double s=0; int k,n=0; cin>>k; do { n++; s+=1.0/n; }while(s-k<1e-12); cout<<n; return 0; }
1088:分离整数的各个数
//1088:分离整数的各个数 #include<iostream> using namespace std; int main(){ int n; cin>>n; do { cout<<n%10<<' '; n/=10; }while(n); return 0; }
1089:数字反转
//1089:数字反转 #include<iostream> using namespace std; int main(){ int n,ans=0,f=1; cin>>n; if(n<0)f=-1,n=-n; do { ans=ans*10+n%10; n/=10; }while(n); ans*=f; cout<<ans; return 0; }
1090:含k个3的数
//1090:含k个3的数 #include<iostream> using namespace std; int main(){ int n,k; cin>>n>>k; do { if(n%10==3)k--; n/=10; }while(n); if(k)cout<<"NO"; else cout<<"YES"; return 0; }
第四节 循环嵌套
1091:求阶乘的和
#include<iostream> using namespace std; long long a[100]; int main(){ int n; long long sum=0; cin>>n; a[0]=1; for(int i=1;i<=n;i++) { a[i]=a[i-1]*i ; sum+=a[i]; } cout<<sum; return 0; }
1092:求出e的值
#include<iostream> #include<iomanip> using namespace std; double a[1000]; int main(){ double n, sum=1; cin>>n; a[0]=1; for(int i=1;i<=n;i++) { a[i]=a[i-1]/i ; sum+=a[i]; } cout<<fixed<<setprecision(10)<<sum; return 0; }
1093:计算多项式的值
#include<iostream> #include<cmath> #include<iomanip> using namespace std; int main() { double x,b; int n; cin>>x>>n; b=(pow(x,n+1)-1)/(x-1); cout<<fixed<<setprecision(2)<<b; return 0; }
1094:与7无关的数
#include<iostream> using namespace std; bool cont(int n) { while(n) { if(n%10==7)return true; n/=10; } return false; } int main(){ int n,sum=0; cin>>n; for(int i=1;i<=n;i++) if(!cont(i)&&(i%7))sum+=i*i; cout<<sum; return 0; }
1095:数1的个数
#include<iostream> using namespace std; int num1(int n) { int sum=0; while(n) { if(n%10==1)sum++; n/=10; } return sum; } int main(){ int n,ans=0; cin>>n; for(int i=1;i<=n;i++) ans+=num1(i); cout<<ans; return 0; }
1096:数字统计
#include<iostream> using namespace std; int num2(int n) { int sum=0; while(n) { if(n%10==2)sum++; n/=10; } return sum; } int main(){ int n,m,ans=0; cin>>n>>m; for(int i=n;i<=m;i++) ans+=num2(i); cout<<ans; return 0; }
1097:画矩形
#include<iostream> using namespace std; void jx(int a,int b,char c,int d) { char e=(d==1?c:' '),f; for(int i=1;i<=a;i++) { for(int j=1;j<=b;j++) { if(i==1||i==a||j==1||j==b)f=c; else f=e; cout<<f; } cout<<endl; } } int main(){ int n,m,a; char b; cin>>n>>m>>b>>a; jx(n,m,b,a); return 0; }
1098:质因数分解
#include<iostream> using namespace std; int main() { int n; cin>>n; for(int i=2;i<=n/i;i++) if(n%i==0) cout<<n/i; return 0; }
1099:第n小的质数
#include<iostream> using namespace std; int a[10001],k=1; bool prime(int n) { for(int i=1;i<=k;i++) if(n%a[i]==0)return false; return true; } int main(){ int n; cin>>n; a[1]=2; for(int i=3;k<=n;i+=2) if(prime(i))a[++k]=i; cout<<a[n]; return 0; }
1100:金币
#include<iostream> using namespace std; int main(){ int n,i=0,sum=0,ans=0; cin>>n; while(sum<=n)sum+=++i; i--; sum-=i+1; for(int j=1;j<=i;j++) ans+=j*j; ans+=(i+1)*(n-sum); cout<<ans; return 0; }
1101:不定方程求解
#include<iostream> using namespace std; int main(){ int a,b,c,ans=0; cin>>a>>b>>c; for(int i=0;i<=c/a;i++) if((c-a*i)%b==0)ans++; cout<<ans; return 0; }
第五章 数 组
第一节 一维数组
1102:与指定数字相同的数的个数
#include<iostream> using namespace std; int main(){ int n,b,c[101],ans=0; cin>>n; for(int i=1;i<=n;i++)cin>>c[i]; cin>>b; for(int i=1;i<=n;i++) if(c[i]==b)ans++; cout<<ans; return 0; }
1103:陶陶摘苹果
#include<iostream> using namespace std; int main(){ int a[11],h,ans=0; for(int i=1;i<=10;i++)cin>>a[i]; cin>>h; for(int i=1;i<=10;i++) if(a[i]<=h+30)ans++; cout<<ans; return 0; }
1104:计算书费
#include<iostream> #include<iomanip> using namespace std; int main(){ float a[11]={0,28.9,32.7,45.6,78,35,86.2,27.8,43,56,65},sum=0; int n; for(int i=1;i<=10;i++) { cin>>n; sum+=a[i]*n; } cout<<fixed<<setprecision(1)<<sum; return 0; }
1105:数组逆序重存放
#include<iostream> using namespace std; int main(){ int n,a[101]; cin>>n; for(int i=n;i>0;i--)cin>>a[i]; for(int i=1;i<=n;i++)cout<<a[i]<<' '; return 0; }
1106:年龄与疾病
#include<iostream> #include<iomanip> using namespace std; int n,b[5],a; int main(){ cin>>n; for(int i=1;i<=n;i++) { cin>>a; if(a<=18)b[1]++; else if(a<=35)b[2]++; else if(a<=60)b[3]++; else b[4]++; } for(int i=1;i<=4;i++)cout<<fixed<<setprecision(2)<<1.0*b[i]/n*100<<'%'<<'\n'; return 0; }
1107:校门外的树
#include<iostream> using namespace std; int a[10001]; int main(){ int l,n,c,b,ans=0; cin>>l>>n; for(int i=1;i<=n;i++) { cin>>c>>b; for(int j=c;j<=b;j++) a[j]=1; } for(int i=0;i<=l;i++) if(a[i]==0)ans++; cout<<ans; return 0; }
1108:向量点积计算
#include<iostream> using namespace std; int main(){ int n,a[1001],b,sum=0; cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=n;i++) { cin>>b; sum+=a[i]*b; } cout<<sum; return 0; }
1109:开关灯
#include<iostream> using namespace std; bool d[5001]; int main(){ int n,m; cin>>n>>m; for(int i=1;i<=m;i++) for(int j=i;j<=n;j++) if(j%i==0)d[j]=!d[j]; cout<<1; for(int i=2;i<=n;i++) if(d[i])cout<<','<<i; return 0; }
1110:查找特定的值
#include<iostream> using namespace std; int n,a[10001],m,i; int main(){ cin>>n; for(i=1;i<=n;i++)cin>>a[i]; cin>>m; i=1; while(a[i]!=m&&i<=n)i++; if(i==n+1)cout<<-1; else cout<<i; return 0; }
1111:不高兴的津津
#include<iostream> using namespace std; int main(){ int n,m,i,s,maxn=0,max=8; for(i=1;i<=7;i++) { cin>>n>>m; if(n+m>max)max=n+m,maxn=i; } cout<<maxn; return 0; }
1112:最大值和最小值的差
#include<iostream> using namespace std; int main(){ int n,m,max=-10001,min=10001; cin>>n; for(int i=1;i<=n;i++) { cin>>m; if(m>max)max=m; if(m<min)min=m; } cout<<max-min; return 0; }
1113:不与最大数相同的数字之和
#include<iostream> using namespace std; int main(){ int n,m,max=-1000001,k,ans=0; cin>>n; for(int i=1;i<=n;i++) { cin>>m; ans+=m; if(m>max) { k=1; max=m; } else if(m==max)k++; } ans-=max*k; cout<<ans; return 0; }
1114:白细胞计数
#include<iostream> #include<iomanip> using namespace std; double a[301],m,max1=-1,max2,min1=(1<<31)-1,min2,sum=0,aver,jd; int main(){ int n; cin>>n; for(int i=1;i<=n;i++) { cin>>m; sum+=m; if(m>max1){ max2=max1; max1=m; } else if(m>max2)max2=m; if(m<min1){ min2=min1; min1=m; } else if(m<min2)min2=m; } aver=(sum-max1-min1)/(n-2); jd=max2-aver>aver-min2?max2-aver:aver-min2; cout<<fixed<<setprecision(2)<<aver<<' '<<jd; return 0; }
1115:直方图
#include<iostream> using namespace std; int a[10002]; int main(){ int n,m,max=-1; cin>>n; for(int i=1;i<=n;i++) { cin>>m; if(max<m)max=m; a[m]++; } for(int i=0;i<=max;i++) cout<<a[i]<<endl; return 0; }
1116:最长平台
#include<iostream> using namespace std; int main(){ int n; int m,fr=-1,ln=1,mn=0; cin>>n; cin>>fr; for(int i=1;i<n;i++) { cin>>m; if(m==fr){ ln++; if(mn<ln)mn=ln; } else ln=1,fr=m; } cout<<mn; return 0; }
1117:整数去重
#include<iostream> using namespace std; int a[20001],b[20001]; int main(){ int n,m,k=0,f=0; cin>>n; for(int i=1;i<=n;i++) { cin>>m; if(!a[m])a[m]=1,b[++f]=m; } for(int i=1;i<=f;i++) if(k==0) { cout<<b[i]; k=1; } else cout<<' '<<b[i]; return 0; }
1118:铺地毯
#include<iostream> using namespace std; int a[10000][4]; int main(){ int n,x,y,ans=0; cin>>n; for(int i=1;i<=n;i++)cin>>a[i][0]>>a[i][1]>>a[i][2]>>a[i][3]; cin>>x>>y; for(int i=n;i>=1;i--) { if(a[i][0]<=x&&x<=a[i][0]+a[i][2]&&a[i][1]<=y&&y<=a[i][1]+a[i][3]) { cout<<i; ans=1; break; } } if(ans==0)cout<<-1; return 0; }
第二节 二维数组
1119:矩阵交换行
#include<iostream> using namespace std; int a[6][6]; int main(){ int n,m; for(int i=1;i<=5;i++) for(int j=1;j<=5;j++)cin>>a[i][j]; cin>>n>>m; for(int i=1;i<=5;i++)swap(a[n][i],a[m][i]); for(int i=1;i<=5;i++) { for(int j=1;j<5;j++) cout<<a[i][j]<<' '; cout<<a[i][5]<<'\n'; } return 0; }
1120:同行列对角线的格
#include<iostream> using namespace std; void pt(int x,int y,int z) { if(z==-1)cout<<' '; cout<<'('<<x<<','<<y<<')'; if(z==1)cout<<' '; if(z==2)cout<<'\n'; } int main(){ int n,i,j,f=0; cin>>n>>i>>j; for(int k=1;k<n;k++) pt(i,k,1); pt(i,n,2); for(int k=1;k<n;k++) pt(k,j,1); pt(n,j,2); for(int k=1;k<=n;k++) if(i-j+1<=k&&k<=n+i-j) if(f==0) { pt(k,k-i+j,0); f=1; } else pt(k,k-i+j,-1); cout<<'\n'; f=0; for(int k=n;k>0;k--) if(i+j-n<=k&&k<=i+j-1) if(f==0) { pt(k,i+j-k,0); f=1; } else pt(k,i+j-k,-1); return 0; }
//1120:同行列对角线的格 #include<cstdio> int main(){ int n,x,y; scanf("%d %d %d",&n,&x,&y); for(int i=1;i<=n;i++)printf("(%d,%d) ",x,i); printf("\n"); for(int i=1;i<=n;i++)printf("(%d,%d) ",i,y); printf("\n"); for(int i=1;i<=n;i++) if(y-x+i>0&&y-x+i<=n)printf("(%d,%d) ",i,y-x+i); printf("\n"); for(int j=1;j<=n;j++) if(x+y-j>0&&x+y-j<=n)printf("(%d,%d) ",x+y-j,j); return 0; }
1121:计算矩阵边缘元素之和
#include<iostream> using namespace std; int main(){ int m,n,sum=0,a[101][101]; cin>>m>>n; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++)cin>>a[i][j]; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) if(i==1||i==m||j==1||j==n)sum+=a[i][j]; cout<<sum; return 0; }
1122:计算鞍点
#include<iostream> using namespace std; int a[6][6],h[6],l[6]; int main(){ int mh,mn,ml,ln,f=0; for(int i=1;i<=5;i++) for(int j=1;j<=5;j++)cin>>a[i][j]; for(int i=1;i<=5;i++) { mh=-1,ml=(1<<31)-1; for(int j=1;j<=5;j++) { if(mh<a[i][j])mh=a[i][j],h[i]=j; if(ml>a[j][i])ml=a[j][i],l[i]=j; } } for(int i=1;i<=5;i++) if(l[h[i]]==i) { cout<<i<<' '<<h[i]<<' '<<a[i][h[i]]<<endl; f=1; } if(f==0)cout<<"not found"; return 0; }
1123:图像相似度
#include<iostream> #include<iomanip> using namespace std; int a[101][101],b[101][101]; int main(){ int m,n,ans=0; cin>>m>>n; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++)cin>>a[i][j]; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) { cin>>b[i][j]; if(b[i][j]==a[i][j])ans++; } cout<<fixed<<setprecision(2)<<1.0*ans/m/n*100; return 0; }
1124:矩阵加法
#include<iostream> #include<iomanip> using namespace std; int a[101][101],b[101][101]; int main(){ int m,n; cin>>m>>n; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++)cin>>a[i][j]; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) { cin>>b[i][j]; a[i][j]+=b[i][j]; } for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++)cout<<a[i][j]<<' '; cout<<endl; } return 0; }
1125:矩阵乘法
#include<iostream> #include<iomanip> using namespace std; int a[101][101],b[101][101],c[101][101]; int main(){ int n,m,k; cin>>n>>m>>k; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)cin>>a[i][j]; for(int i=1;i<=m;i++) for(int j=1;j<=k;j++)cin>>b[i][j]; for(int i=1;i<=n;i++) for(int j=1;j<=k;j++) for(int l=1;l<=m;l++) c[i][j]+=a[i][l]*b[l][j]; for(int i=1;i<=n;i++) { for(int j=1;j<=k;j++) cout<<c[i][j]<<' '; cout<<endl; } return 0; }
1126:矩阵转置
#include<iostream> using namespace std; int a[101][101],b[101][101]; int main(){ int n,m; cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)cin>>a[i][j]; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) b[i][j]=a[j][i]; for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) cout<<b[i][j]<<' '; cout<<endl; } return 0; }
1127:图像旋转
#include<iostream> using namespace std; int a[101][101],b[101][101]; int main(){ int n,m; cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)cin>>a[i][j]; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) b[i][j]=a[n+1-j][i]; for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) cout<<b[i][j]<<' '; cout<<endl; } return 0; }
1128:图像模糊处理
#include<iostream> using namespace std; int a[101][101],b[101][101]; int main(){ int n,m; cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)cin>>a[i][j]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(i==1||i==n||j==1||j==m) b[i][j]=a[i][j]; else b[i][j]=((a[i][j]+a[i-1][j]+a[i+1][j]+a[i][j-1]+a[i][j+1])/5.0+0.5); } for(int i=1;i<=n;i++) { for(int j=1;j<m;j++) cout<<b[i][j]<<' '; cout<<b[i][m]<<endl; } return 0; }
第三节 字符类型和字符数组
1129:统计数字字符个数
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int main(){ char ch[10000]; int ans=0; gets(ch); for(int i=0;i<strlen(ch);i++) if('0'<=ch[i]&&ch[i]<='9')ans++; cout<<ans; return 0; }
1130:找第一个只出现一次的字符
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int b[26]; string ch; int main(){ getline(cin,ch); for(int i=0;i<ch.size();i++) b[ch[i]]++; for(int i=0;i<ch.size();i++) if(b[ch[i]]==1) { cout<<ch[i]; return 0; } cout<<"no"; return 0; }
1131:基因相关性
#include<iostream> #include<cstring> using namespace std; int main(){ double n,m; cin>>n; string s1,s2; cin>>s1>>s2; int s=s1.size(),ans=0; for(int i=0;i<s;i++) if(s1[i]==s2[i])ans++; m=ans*1.0/s; if(m-n>1e-16)cout<<"yes"; else cout<<"no"; return 0; }
1132:石头剪子布
#include<iostream> using namespace std; int si(string s) { if(s=="Rock")return 0; if(s=="Scissors")return 1; if(s=="Paper")return 2; } int main(){ string p1,p2,re[3]={"Tie","Player2","Player1"}; int n,a,b,ans[101]; cin>>n; for(int i=1;i<=n;i++) { cin>>p1>>p2; ans[i]=(si(p1)-si(p2)+3)%3; } for(int i=1;i<=n;i++) cout<<re[ans[i]]<<endl; return 0; }
1133:输出亲朋字符串
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int main(){ string s1; char s2[101]; cin>>s1; int n=s1.size(); for(int i=0;i<n-1;i++) s2[i]=s1[i]+s1[i+1]; s2[n-1]=s1[n-1]+s1[0]; s2[n]='\0'; cout<<s2; return 0; }
1134:合法C标识符查
#include<bits/stdc++.h> using namespace std; char a[21]; int main() { int ans=0; scanf("%s",a); int len=strlen(a); for(int i=0;i<len;i++) { int ch=a[i]; if(!(ch>='0'&&ch<='9'||ch>='A'&&ch<='Z'||ch=='_'||ch>='a'&&ch<='z'))ans=1; } if(a[0]>='0'&&a[0]<='9')ans=1; if(ans==0)cout<<"yes"; else cout<<"no"; return 0; }
1135:配对碱基链
#include<iostream> #include<cstring> using namespace std; char atgc(char ch) { switch(ch){ case 'A':return 'T'; case 'T':return 'A'; case 'G':return 'C'; default:return 'G';} } int main(){ char s1[256],s2[256]; cin>>s1; int n=strlen(s1); for(int i=0;i<n;i++) cout<<atgc(s1[i]); return 0; }
1136:密码翻译
#include<iostream> #include<cstring> #include<cstdio> using namespace std; char ed(char ch) { if(ch>='a'&&ch<='y')return ch+1; if(ch>='A'&&ch<='Y')return ch+1; if(ch=='z')return 'a'; if(ch=='Z')return 'A'; return ch; } int main(){ char c[81]; gets(c); int n=strlen(c); for(int i=0;i<n;i++) cout<<ed(c[i]); return 0; }
1137:加密的病历单
#include<iostream> #include<cstdio> #include<cstring> using namespace std; char ed(char ch) { if(ch>96)ch=(ch-94)%26+65; else ch=(ch-62)%26+97; return ch; } int main(){ char s[51]; cin>>s; int n=strlen(s); for(int i=n-1;i>=0;i--) cout<<ed(s[i]); return 0; }
1138:将字符串中的小写字母转换成大写字母
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int main(){ char ch[101]; gets(ch); int n=strlen(ch); for(int i=0;i<n;i++) { if(ch[i]>='a'&&ch[i]<='z')ch[i]-=32; cout<<ch[i]; } return 0; }
1139:整理药名
#include<iostream> #include<cstdio> #include<cstring> using namespace std; string ed(string ch) { if(ch[0]>='a'&&ch[0]<='z')ch[0]-=32; int n=ch.size() ; for(int i=1;i<n;i++) if(ch[i]>='A'&&ch[i]<='Z')ch[i]+=32; return ch; } int main(){ string s[101]; int n; cin>>n; for(int i=1;i<=n;i++)cin>>s[i]; for(int i=1;i<=n;i++)cout<<ed(s[i])<<endl;; return 0; }
1140:验证子串
#include<iostream> #include<cstring> using namespace std; int main(){ string s1,s2; cin>>s1>>s2; int n1=s1.size() ,n2=s2.size() ,an=0; if(n1>n2){ swap(s1,s2); swap(n1,n2); } for(int i=0;i<=n2-n1;i++) { an=0; while(an<n1&&s1[an]==s2[an+i])an++; if(an==n1) { cout<<s1<<" is substring of "<<s2; return 0; } } cout<<"No substring"; return 0; }
1141:删除单词后缀
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int main() { string s; cin>>s; int n=s.size() ; if(s.substr(n-2,2)=="er"||s.substr(n-2,2)=="ly" ) s=s.substr(0,n-2); else if(s.substr(n-3,3)=="ing" ) s=s.substr(0,n-3); cout<<s; return 0; }
1142:单词的长度
#include<iostream> using namespace std; string s; int main() { int f=0; while(cin>>s) { int len=s.size(); if(f)cout<<','; cout<<len; f=1; } return 0; }
1143:最长最短单词
#include<iostream> #include<cstring> #include<cstdio> #include<string> using namespace std; int main() { string s,mx,mi; int h=0,max=0,min=101,m,l; getline(cin,s); //s+=" "; m=s.size() ; for(int j=0;j<=m;j++) { if(s[j]==' '||s[j]==','||s[j]=='\0') { if(h!=j) { l=j-h; if(l<min) { min=l; mi=s.substr(h,l); } if(l>max) { max=l; mx=s.substr(h,l); } } h=j+1; } else if(h==j)h=j; } cout<<mx<<endl<<mi; return 0; }
1144:单词翻转
#include<iostream> #include<cstring> #include<cstdio> using namespace std; string retu(string ss) { int n=ss.size() ; for(int i=0;i<=(n-1)/2;i++) swap(ss[i],ss[n-1-i]); return ss; } int main(){ string s,ss="",st; int h=0,l; getline(cin,s); for(int i=0;i<=s.size();i++) { if(s[i]==' '||s[i]=='\0') { if(i!=h) { l=i-h; st=s.substr(h,l); ss+=retu(st); } if(s[i]=32)ss+=s[i]; h=i+1; } } cout<<ss.substr(0,s.size())<<endl; return 0; }
1145:字符串p型编码
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int main(){ string s; int l=1; getline(cin,s); for(int i=0;i<s.size() ;i++) { if(s[i]==s[i+1])l++; else { cout<<l<<s[i]; l=1; } } return 0; }
1146:判断字符串是否为回文
#include<iostream> #include<cstring> #include<cstdio> using namespace std; bool pd(string s) { int n=s.size(); for(int i=0;i<=(n-1)/2;i++) if(s[i]!=s[n-1-i])return false; return true; } int main(){ string s; getline(cin,s); if(pd(s))cout<<"yes"; else cout<<"no"; return 0; }
1147:最高分数的学生姓名
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int main(){ int n; int cj[101],max=-1,maxn; string xm[101]; cin>>n; for(int i=1;i<=n;i++) { cin>>cj[i]>>xm[i]; if(cj[i]>max)max=cj[i],maxn=i; } cout<<xm[maxn]; return 0; }
1148:连续出现的字符
#include <bits/stdc++.h> using namespace std; int main() { char s[2502],old; int i,t=1,k,l; scanf("%d",&k); scanf("%s",s); l=strlen(s); old=s[0]; for(i=1;i<l;++i) { if(s[i]==old) //如果下一项与该项相同,次数就加1 { ++t; if(t==k) //如果次数已达到k次,就输出结束 { cout<<s[i]; return 0; } } else t=1; old=s[i]; } printf("No\n"); return 0; }
1149:最长单词2
#include<iostream> #include<string> #include<cstring> #include<bits/stdc++.h> using namespace std; int main() { string s,max; int maxn=0,f=0,l; getline(cin,s,'.'); for(int i=0;i<=s.size();i++) if(s[i]==32||s[i]==0) { l=i-f; if(l>maxn) { maxn=l; max=s.substr(f,l); } f=i+1; } cout<<max; return 0; }
第六章 函数
第一节 函数
1150:求正整数2和n之间的完全数
#include<iostream> using namespace std; int main(){ int m,n,ans; cin>>m; for(int n=2;n<=m;n++) { ans=1; for(int i=2;i<=n/2;i++) if(n%i==0)ans+=i; if(ans==n)cout<<n<<endl; } return 0; }
1151:素数个数
#include<iostream> using namespace std; bool pri(int n) { for(int i=2;i<=n/i;i++) if(n%i==0)return false; return true; } int main(){ int n,ans=0; cin>>n; for(int i=2;i<=n;i++) if(pri(i))ans++; cout<<ans; return 0; }
1152:最大数max(x,y,z)
#include<iostream> #include<iomanip> using namespace std; int max2(int a,int b) { if(a>=b)return a; else return b; } int max(int a,int b,int c) { return max2(max2(a,b),c); } int main(){ int a,b,c; cin>>a>>b>>c; cout<<fixed<<setprecision(3)<<1.0*max(a,b,c)/max(a+b,b,c)/max(a,b,b+c); return 0; }
1153:绝对素数
#include<iostream> using namespace std; bool pri(int n) { for(int i=2;i<=n/i;i++) if(n%i==0)return false; return true; } int retu(int n) { return n%10*10+n/10; } int main(){ for(int i=11;i<98;i++) if(pri(i)&&pri(retu(i))) cout<<i<<endl; return 0; }
1154:亲和数
#include<iostream> using namespace std; int pm(int n) { int ans=1; for(int i=2;i<n;i++) if(n%i==0)ans+=i; return ans; } int main(){ for(int i=3;;i++) if(pm(i)!=i&&pm(pm(i))==i) { cout<<i<<' '<<pm(i); break; } return 0; }
1155:回文三位数
#include<iostream> using namespace std; bool hw(int i) { return i/100==i%10; } bool pri(int n) { for(int i=2;i<=n/i;i++) if(n%i==0)return false; return true; } int main(){ for(int i=101;i<=999;i++) if(pri(i)&&hw(i))cout<<i<<endl; return 0; }
1156:求π的值
#include<iostream> #include<iomanip> #include<cmath> using namespace std; int main() { double tmp,x=1.0/sqrt(3),key=0; int i=1; tmp=x; while(tmp>1e-6) { key+=6*tmp*(i%2?1:-1); tmp*=x*x*(2*i-1)/(2*i+1); i++; } cout<<fixed<<setprecision(10)<<key; return 0; }
1157:哥德巴赫猜想
#include<iostream> using namespace std; bool pri(int n) { for(int i=2;i<=n/i;i++) if(n%i==0)return false; return true; } int main(){ for(int i=6;i<=100;i+=2) for(int j=2;j<i;j++) if(pri(j)&&pri(i-j)) { cout<<i<<'='<<j<<'+'<<i-j<<endl; break; } return 0; }
1397:简单算术表达式求值
#include<bits/stdc++.h> using namespace std; int a[100001]; char c[100001]; int main() { int n,k=0; char ch; cin>>a[0]; //while(ch=getchar()) { ch=getchar(); cin>>n; switch(ch) { case '*':a[k]*=n;break; case '/':a[k]/=n;break; case '%':a[k]%=n;break; case '+':a[++k]=n;c[k]='+';break; case '-':a[++k]=n;c[k]='-';break; default:break; } } for(int i=1;i<=k;i++) if(c[i]=='+')a[0]+=a[i]; else a[0]-=a[i]; cout<<a[0]; return 0; }
1398:短信计费
#include<bits/stdc++.h> using namespace std; int main() { int n,m,ans=0; cin>>n; for(int i=1;i<=n;i++) { cin>>m; ans+=(m+69)/70; } cout<<fixed<<setprecision(1)<<ans/10.0; return 0; }
1399:甲流病人初筛
#include<iostream> using namespace std; struct pp { string name; float tw; int ks; bool jl; void ip() { cin>>name>>tw>>ks; if(tw>=37.5&&ks)jl=true; } } p[201]; int main(){ int n,ans=0; cin>>n; for(int i=1;i<=n;i++) { p[i].ip(); if(p[i].jl)ans++; } for(int i=1;i<=n;i++) if(p[i].jl)cout<<p[i].name<<endl; cout<<ans; return 0; }
1400:统计单词数
#include<iostream> #include<cstring> #include<cstdio> using namespace std; string s,ss; int main(){ getline(cin,s); getline(cin,ss); for(int i=0;i<s.size();i++)if(s[i]<='Z'&&s[i]>='A')s[i]+=32; for(int i=0;i<ss.size();i++)if(ss[i]<='Z'&&ss[i]>='A')ss[i]+=32; int f=0,st=-1,n=0,sn=s.size(),ssn=ss.size() ; for(int i=0;i<=ssn;i++) { if(ss[i]==32||ss[i]==0) { if(f==sn&&ss.substr(i-sn,sn)==s) { n++; if(st<0)st=i-sn; } f=0; } else f++; } if(st==-1)cout<<-1; else cout<<n<<' '<<st; return 0; }
1401:机器翻译
#include<iostream> using namespace std; int a[1000],b[1000]; int main(){ int m,n,s=0,l=0,j,ans=0;//s代表个数,l代表位置 cin>>m>>n; for(int i=0;i<n;i++) { cin>>a[i]; for(j=0;j<s;j++)if(b[j]==a[i])break; if(j==s) { ans++; if(s<m)b[s++]=a[i]; else { b[l]=a[i]; l++; if(l==m)l=0; } } } cout<<ans; return 0; }
1402:Vigenère密码
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int c[100]; char m[1000],n[1000]; int main(){ string s; int cn,mn,t; cin>>s; cn=s.size() ; for(int i=0;i<cn;i++) c[i]=(s[i]-'A')%32; cin>>s; mn=s.size() ; for(int i=0;i<mn;i++) { t=s[i]-'A'; n[i]=t/32*32+'A'+(t%32-c[i%cn]+26)%26; } cout<<n; return 0; }
1403:素数对
#include<iostream> using namespace std; bool pri(int n) { for(int i=2;i<=n/i;i++) if(n%i==0)return false; return true; } int main(){ int n,f=0; cin>>n; for(int i=3;i<=n;i+=2) if(pri(i)&&pri(i+2)) { cout<<i<<' '<<i+2<<endl; f=1; } if(!f)cout<<"empty"; return 0; }
1404:我家的门牌号
#include<iostream> using namespace std; int main(){ int n; cin>>n; for(int i=1;i<1000;i++) if((i*i+i-n*2>0)&&(i*i+i-n*2)%6==0) { cout<<(i*i+i-n*2)/6<<' '<<i; return 0; } }
1405:质数的和与积
#include<iostream> using namespace std; bool pri(int n) { for(int i=2;i<=n/i;i++) if(n%i==0)return false; return true; } int main(){ int n; cin>>n; for(int i=n/2;i>1;i--) if(pri(i)&&pri(n-i)) { cout<<i*(n-i); return 0; } }
1406:单词替换
#include<iostream> #include<cstring> #include<cstdio> using namespace std; string s,ss[200],ans; int main(){ int i; while(cin>>s) { ss[i]=s; i++; } i--; for(int j=0;j<i-1;j++) { if(ss[j]==ss[i-1])cout<<ss[i]; else cout<<ss[j]; if(j<i-2)cout<<' '; } return 0; }
1407:笨小猴
#include<iostream> using namespace std; int mx,mn=100,a[26]; bool pri(int n) { if(n<2)return false; for(int i=2;i<=n/i;i++) if(n%i==0)return false; return true; } bool luck(string s) { int sl=s.size() ; for(int i=0;i<sl;i++) a[s[i]-'a']++; for(int i=0;i<26;i++) { if(a[i]>mx)mx=a[i]; if(a[i]<mn&&a[i])mn=a[i]; } mx-=mn; if(pri(mx))return true; else return false; } int main(){ string ss; cin>>ss; if(luck(ss))cout<<"Lucky Word\n"<<mx; else cout<<"No Answer\n0"; return 0; }
1408:素数回文数的个数
#include<iostream> using namespace std; int a[100]; bool pri(int n) { for(int i=2;i<=n/i;i++) if(n%i==0)return false; return true; } bool hw(int n) { if(n<10)return true; int i=0; while(n) { a[i++]=n%10; n/=10; } i--; for(int j=0;j<=i/2;j++) if(a[j]!=a[i-j])return false; return true; } int main(){ int n,ans=0; cin>>n; for(int i=11;i<=n;i++) if(pri(i)&&hw(i)) ans++; cout<<ans; return 0; }
1409:判决素数个数
#include<iostream> using namespace std; bool pri(int n) { if(n<2)return false; for(int i=2;i<=n/i;i++) if(n%i==0)return false; return true; } int main(){ int n,m,ans=0; cin>>n>>m; for(int i=n;i<=m;i++) if(pri(i))ans++; cout<<ans<<endl; return 0; }
1410:最大质因子序列
#include<iostream> using namespace std; bool pri(int n) { if(n<2)return false; for(int i=2;i<=n/i;i++) if(n%i==0)return false; return true; } int main(){ int n,m; cin>>n>>m; for(int i=n;i<=m;i++) { for(int j=i;j>=2;j--) if(pri(j)&&!(i%j)) { cout<<j; break; } if(i<m)cout<<','; } return 0; }
1411:区间内的真素数
#include<iostream> using namespace std; bool pri(int n) { if(n<2)return false; for(int i=2;i<=n/i;i++) if(n%i==0)return false; return true; } int dx(int n) { int ans=0; while(n) { ans=ans*10+n%10; n/=10; } return ans; } int main(){ int n,m,f=0; cin>>n>>m; for(int i=n;i<=m;i++) if(pri(i)&&pri(dx(i))) if(f)cout<<','<<i; else { cout<<i; f=1; } if(f==0)cout<<"No"; return 0; }
1412:二进制分类
#include<iostream> using namespace std; bool fl(int n) { int k=0,js=0,os=0,t; do { t=n/(1<<k); if(t%2)js++; else os++; k++; }while(n>=(1<<k)); return js>os; } int main(){ int a=0,b=0; for(int i=1;i<=1000;i++) if(fl(i))a++; else b++; cout<<a<<' '<<b; return 0; }
1413:确定进制
#include<iostream> #include<cmath> using namespace std; int zh(int n,int m) { int k=0,an=0; while(n) { an+=pow(m,k)*(n%10); n/=10; k++; } return an; } int mxb(int n) { int mx=0; while(n) { if(n%10>mx)mx=n%10; n/=10; } return mx; } int main(){ int p,q,r; cin>>p>>q>>r; for(int i=max(max(mxb(p),mxb(q)),mxb(r))+1;i<=40;i++) { // cout<<zh(p,i)<<' '<<zh(q,i)<<' '<<zh(r,i)<<' '<<i<<endl; if(zh(p,i)*zh(q,i)==zh(r,i)) { cout<<i; return 0; } } cout<<0; return 0; }
第二节 递归算法
1158:求1+2+3+...
#include<iostream> using namespace std; int sum(int n) { if(n==1)return 1; else return n+sum(n-1); } int main(){ int n; cin>>n; cout<<sum(n); return 0; }
1159:斐波那契数列
#include<iostream> using namespace std; int fblq(int n) { if(n==1)return 0; if(n==2)return 1; return fblq(n-1)+fblq(n-2); } int main(){ int n; cin>>n; cout<<fblq(n); return 0; }
1160:倒序数
#include<iostream> using namespace std; int retu(int n) { int m=0; while(n) { m=m*10+n%10; n/=10; } return m; } int main(){ int n; cin>>n; cout<<retu(n); return 0; }
1161:转进制
#include<iostream> #include<cstdio> #include<cstring> using namespace std; char a[1000]; void retu(int n,int m) { int i=0,t; while(n) { t=n%m; a[i++]=(t>9?t-10+'A':t+'0'); n/=m; } a[i]='\0'; return; } int main(){ int n,m; cin>>n>>m; retu(n,m); for(int i=strlen(a)-1;i>=0;i--)cout<<a[i]; return 0; }
1162:字符串逆序
#include<iostream> #include<cstring> using namespace std; int main(){ string s; getline(cin,s,'!'); for(int i=s.size()-1;i>=0;i-- ) cout<<s[i]; return 0; }
1163:阿克曼(Ackmann)函数
#include<iostream> using namespace std; int akm(int m,int n) { if(m==0)return n+1; if(m>0&&n==0)return akm(m-1,1); return akm(m-1,akm(m,n-1)); } int main(){ int n,m; cin>>m>>n; cout<<akm(m,n); return 0; }
1164:digit函数
#include<iostream> using namespace std; int a[10001]; int main(){ int n,k,i=0; cin>>n>>k; while(n&&i<k) { a[i++]=n%10; n/=10; } cout<<a[k-1]; return 0; }
1165:Hermite多项式
#include<bits/stdc++.h> using namespace std; double hermite(int,int); int main() { int n,x; cin>>n>>x; cout<<fixed<<setprecision(2)<<hermite(n,x); return 0; } double hermite(int n,int x) { if(n==0)return 1; if(n==1)return 2*x; return 2*x*hermite(n-1,x)-2*(n-1)*hermite(n-2,x); }
1166:求f(x,n)
#include<iostream> #include<cmath> #include<iomanip> using namespace std; float kf(float x,int n); int main() { float x; int n; cin>>x>>n; cout<<fixed<<setprecision(2)<<kf(x,n); return 0; } float kf(float x,int n) { if(n==1)return sqrt(1+x); return sqrt(n+kf(x,n-1)); }
1167:再求f(x,n)
#include<iostream> #include<iomanip> using namespace std; double f(int n,double x) { if(n==1)return x/(1+x); return x/(n+f(n-1,x)); } int main() { int n; double x; cin>>x>>n; cout<<fixed<<setprecision(2)<<f(n,x); return 0; }
第二部分:基础算法
第一章 高精度计算
1307:【例1.3】高精度乘法
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int a[101],b[101],c[201]; int main(){ string s; cin>>s; int la=s.size(),x=0; for(int i=0;i<la;i++)a[la-1-i]=s[i]-'0'; cin>>s; int lb=s.size(); for(int i=0;i<lb;i++)b[lb-1-i]=s[i]-'0'; for(int i=0;i<la;i++) { int k; for(int j=0;j<lb;j++) { k=i+j; c[k]+=a[i]*b[j]+x; x=c[k]/10; c[k]%=10; } while(x) { c[++k]=x; x/=10; } } int kk=201; while(!c[kk]&&kk) kk--; if(kk) for(int i=kk;i>=0;i--)cout<<c[i]; else cout<<c[0]; return 0; }
1308:【例1.5】高精除
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int a[305],b[305],c[305],d,i; void init(int a[]) {string s; cin>>s; a[0]=s.length(); for(i=1;i<=a[0];i++) a[i]=s[a[0]-i]-'0';//减法倒序存储 } void print(int a[]) {int i; if(a[0]==0){cout<<0<<endl;return;} for(i=a[0];i>0;i--)cout<<a[i]; cout<<endl; return; //函数执行完毕回到主程序 } int compare(int a[],int b[]) {int i; if(a[0]>b[0]) return 1; if(a[0]<b[0]) return-1; for(i=a[0];i>0;i--)//如果两数位数相等,则按位比大小 {if(a[i]>b[i]) return 1; if(a[i]<b[i])return -1; //按位比较若该位数相同,则判断下一位 } return 0;//如果返回0则表示两数相等 } void jian(int a[],int b[]) { int flag,i; flag=compare(a,b); if(flag==0){a[0]=0;return;} if(flag==1) {for(i=1;i<=a[0];i++) { if(a[i]<b[i]){a[i+1]--;a[i]=a[i]+10;} a[i]-=b[i]; } while(a[0]>0&&a[a[0]]==0)a[0]--; return; } } void numcpy(int p[],int q[],int det) { for(int i=1;i<=p[0];i++) q[i+det-1]=p[i]; q[0]=p[0]+det-1; //for(int i=q[0];i>0;i--) cout<<q[i]; //cout<<endl; 打印复制后的数字,方便理解算法,此算法主要采用低位补0做减法 } void chugao(int a[],int b[],int c[]) { int i,tmp[101]; c[0]=a[0]-b[0]+1; //商的位数不超过被除数的位数-除数的位数+1 for(i=c[0];i>0;i--) //每次循环确定某位商的的值,从高位开始 {memset(tmp,0,sizeof(tmp)); numcpy(b,tmp,i); while(compare(a,tmp)>=0){c[i]++;jian(a,tmp);} } while(c[0]>0&&c[c[0]]==0) c[0]--; return; } int main() {init(a);init(b); chugao(a,b,c); print(c); print(a); return 0; }
1309:【例1.6】回文数(Noip1999)
#include<iostream> #include<cstring> using namespace std; int n,ans,len,source[10000]; char temp[10000]; bool hw() { for(int i=0;i<(len+1)/2;i++) if(source[i]!=source[len-1-i])return false; return true; } void turn() { int jw=0; for(int i=0;i<(len+1)/2;i++)source[i]=source[len-1-i]=source[i]+source[len-1-i]; for(int i=0;i<len;i++) { source[i]+=jw; jw=source[i]/n; source[i]%=n; } if(jw==1) source[len++]=1; } int main(){ cin>>n>>temp; len=strlen(temp); for(int i=0;i<len;i++) { int tt=temp[len-1-i]; if(tt>=97)tt-=87; if(tt>=65)tt-=55; if(tt>='0')tt-='0'; source[i]=tt; } while(!hw()&&ans<31) { turn(); ans++; } if(ans<30)cout<<ans<<endl; else cout<<"Impossible\n"; return 0; }
1168:大整数加法
#include<iostream> #include<cstring> using namespace std; int a[201],b[201],la,lb; char ca[201],cb[201]; int main() { cin>>ca>>cb; la=strlen(ca),lb=strlen(cb); for(int i=0;i<la;i++) a[la-i-1]=ca[i]-'0'; for(int i=0;i<lb;i++) b[lb-i-1]=cb[i]-'0'; for(int i=0;i<la||i<lb;i++) { a[i]+=b[i]; a[i+1]+=a[i]/10; a[i]%=10; } int i=200; while(a[i]==0)i--; for(int j=i;j>=0;j--)cout<<a[j]; return 0; }
1169:大整数减法
#include<iostream> #include<cstring> using namespace std; int a[201],b[201],la,lb; char ca[201],cb[201]; int main() { cin>>ca>>cb; la=strlen(ca),lb=strlen(cb); for(int i=0;i<la;i++) a[la-i-1]=ca[i]-'0'; for(int i=0;i<lb;i++) b[lb-i-1]=cb[i]-'0'; for(int i=0;i<la||i<lb;i++) { a[i]+=10-b[i]; a[i+1]+=a[i]/10-1; a[i]%=10; } int i=200; while(a[i]==0)i--; for(int j=i;j>=0;j--)cout<<a[j]; return 0; }
1170:计算2的N次方
#include<iostream> using namespace std; int main() { int n,a[100]={0,1},ln=1,x; cin>>n; for(int i=1;i<=n;i++) { x=0; for(int j=1;j<=ln;j++) { a[j]=a[j]*2+x; x=a[j]/10; a[j]%=10; } if(x) { ln++; a[ln]=1; } } for(int i=ln;i>0;i--)cout<<a[i]; return 0; }
1171:大整数的因子
#include <iostream> #include<cstring> #include<cstdio> using namespace std; int a[101]; int main() { string s; int res,ln,flag=0; getline(cin,s); ln=s.size() ; for(int i=0;i<ln ;i++) a[i]=s[i]-'0'; for(int j=2;j<=9;j++) { res=0; for(int i=0;i<ln;i++) { res=res*10+a[i]; res%=j; } if(res==0) { if(flag==0) { cout<<j; flag=1; } else cout<<' '<<j; } } if(flag==0)cout<<"none"; return 0; }
1172:求10000以内n的阶乘
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int a[100001]; int main() { int ln=1,n,x=0; cin>>n; a[0]=1; for(int i=1;i<=n;i++) { x=0; for(int j=0;j<ln;j++) { a[j]=a[j]*i+x; x=a[j]/10; a[j]%=10; } while(x) { a[ln++]=x%10; x/=10; } } for(int i=ln-1;i>=0;i--)cout<<a[i]; //cout<<'\n'<<ln;1 //输出共有多少位数 return 0; }
1173:阶乘和
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int a[10000],s[10000],la,ls=1,x; void jc(int n) { a[0]=1,la=1; for(int i=1;i<=n;i++) { x=0; for(int j=0;j<la;j++) { a[j]=a[j]*i+x; x=a[j]/10; a[j]%=10; } while(x) { a[la++]=x%10; x/=10; } } return; } void pl() { int i,x=0; for(i=0;i<la||i<ls;i++) { s[i]+=a[i]+x; x=s[i]/10; s[i]%=10; } if(x)a[i]=1; ls=i; return; } int main() { int ln=1,n,x=0; cin>>n; for(int i=1;i<=n;i++) { jc(i); pl(); } for(int i=ls-1;i>=0;i--)cout<<s[i]; //cout<<'\n'<<ln;1 //输出共有多少位数 return 0; }
1174:大整数乘法
#include<iostream> #include<cstring> #include<string> using namespace std; int a[1000],b[1000],c[1000]; int main() { string cs,bcs; cin>>bcs>>cs; int bn=bcs.size() ,cn=cs.size() ,x=0,ln; for(int i=0;i<bn ;i++)a[bn-1-i]=bcs[i]-'0'; for(int i=0;i<cn ;i++)b[cn-1-i]=cs[i]-'0'; for(int i=0;i<bn;i++) for(int j=0;j<cn;j++) c[i+j]+=a[i]*b[j]; int i; for(i=0;i<bn+cn-1;i++) { c[i]+=x; x=c[i]/10; c[i]%=10; } while(x) { c[i++]=x%10; x/=10; } ln=i; for(i=ln-1;i>=0;i--)cout<<c[i]; return 0; }
1175:除以13
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int a[101],b[101]; int main() { string s; cin>>s; int ln,res=0,sn=0,t; ln=s.size() ; for(int i=ln-1;i>=0;i--)a[i]=s[i]-'0'; for(int i=0;i<ln;i++) { res=res*10+a[i]; b[i]=res/13; res%=13; } t=0; while(b[t]==0)t++; for(int i=t;i<ln;i++)cout<<b[i]; cout<<'\n'<<res; return 0; }
第二章 数据排序
1310:【例2.2】车厢重组
#include<iostream> using namespace std; int a[10001]; int main() { int n,fl,ans=0; cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=n;i++) { fl=0; for(int j=n;j>i;j--) if(a[j]<a[j-1])swap(a[j],a[j-1]),fl=1,ans++; if(!fl)break; } //for(int i=1;i<=n;i++)cout<<a[i]<<' '; cout<<ans; return 0; }
1311:【例2.5】求逆序对
//1311:【例2.5】求逆序对 #include<iostream> using namespace std; typedef long long nt; nt a[100005],b[100005],ans; void gbs(nt l,nt r) { if(l==r)return; nt mid=(l+r)>>1; gbs(l,mid); gbs(mid+1,r); nt i=l,j=mid+1,k=l; while(i<=mid&&j<=r) { if(a[i]<=a[j])b[k++]=a[i++]; else b[k++]=a[j++],ans+=mid-i+1; } for(nt m=i;m<=mid;m++)b[k++]=a[m]; for(nt m=j;m<=r;m++)b[k++]=a[m]; for(nt m=l;m<=r;m++)a[m]=b[m]; } int main() { nt n; cin>>n; for(nt i=1;i<=n;i++) cin>>a[i]; gbs(1,n); cout<<ans<<endl; //for(int i=1;i<=n;i++) cout<<a[i]<<' '; return 0; }
1176:谁考了第k名
#include<bits/stdc++.h> struct st { int xh; float cj; }stu[10001]; int main() { int n,k,l; scanf("%d %d",&n,&k); for(int i=1;i<=n;i++)scanf("%d %f",&stu[i].xh,&stu[i].cj); for(int i=1;i<=n;i++) { l=i; for(int j=i+1;j<=n;j++) if(stu[j].cj>stu[l].cj)l=j; st tmp; tmp=stu[l]; stu[l]=stu[i]; stu[i]=tmp; } printf("%d %g",stu[k].xh,stu[k].cj); return 0; }
1177:奇数单增序列
#include<iostream> using namespace std; int a[101],b[101]; int main() { int n,l=0,t; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; if(a[i]%2)b[++l]=a[i]; } for(int i=1;i<=l;i++) for(int j=1;j<l;j++) if(b[j]>b[j+1]) { t=b[j]; b[j]=b[j+1]; b[j+1]=t; } cout<<b[1]; for(int i=2;i<=l;i++)cout<<','<<b[i]; return 0; }
1178:成绩排序
#include<iostream> #include<algorithm> using namespace std; struct queue { string name; int scord; }a[22]; bool cmp(queue x,queue y) { if(x.scord==y.scord) return x.name<y.name; else return x.scord>y.scord; } int main() { int n; cin>>n; for(int i=1;i<=n;i++) cin>>a[i].name>>a[i].scord; sort(a+1,a+1+n,cmp); for(int i=1;i<=n;i++) //cout<<a[i].name>>" ">>a[i].scord>>endl; cout<<a[i].name<<" "<<a[i].scord<<endl; return 0; }
1179:奖学金
#include<bits/stdc++.h> using namespace std; struct st { int xh,yw,sx,yy,zf; void inp(int n) { cin>>yw>>sx>>yy; xh=n; zf=yw+sx+yy; } bool operator > (st x) { if(zf==x.zf) if(yw==x.yw)return xh<x.xh; else return yw>x.yw; else return zf>x.zf; } }; bool cmp(st x,st y) { return x>y; } int main() { st a[301]; int n; cin>>n; for(int i=1;i<=n;i++)a[i].inp(i); sort(a+1,a+n+1,cmp); for(int i=1;i<=5;i++)cout<<a[i].xh<<' '<<a[i].zf<<'\n'; return 0; }
1180:分数线划定
#include<iostream> #include<algorithm> using namespace std; struct stu { int xh,cj; } st[10000]; bool cmp(stu a,stu b) { if(a.cj!=b.cj)return a.cj>b.cj; else return a.xh<b.xh; } int main(){ int n,m,rs,fs; cin>>n>>m; for(int i=0;i<n;i++)cin>>st[i].xh>>st[i].cj; sort(st,st+n,cmp); rs=m*1.5; if(rs>n)rs=n; fs=st[rs-1].cj; while(rs<n&&st[rs].cj==fs)rs++; cout<<fs<<' '<<rs<<'\n'; for(int i=0;i<rs;i++) cout<<st[i].xh<<' '<<st[i].cj<<'\n'; return 0; }
1181:整数奇偶排序
#include<iostream> #include<algorithm> using namespace std; int a[10],b[10],la,lb; bool cmp(int x,int y) { return x>y; } int main(){ int n; for(int i=0;i<10;i++) { cin>>n; if(n%2)a[la++]=n; else b[lb++]=n; } sort(a,a+la,cmp); sort(b,b+lb); for(int i=0;i<la;i++)cout<<a[i]<<' '; for(int i=0;i<lb-1;i++)cout<<b[i]<<' '; cout<<b[lb-1]; return 0; }
1182:合影效果
#include<iostream> #include<algorithm> #include<iomanip> using namespace std; float a[40],b[40]; int la,lb; bool cmp(float x,float y) { return x>y; } int main(){ int n; string s; cin>>n; for(int i=0;i<n;i++) { cin>>s; if(s=="male")cin>>a[la++]; else cin>>b[lb++]; } sort(a,a+la); sort(b,b+lb,cmp); for(int i=0;i<la;i++)cout<<fixed<<setprecision(2)<<a[i]<<' '; for(int i=0;i<lb-1;i++)cout<<fixed<<setprecision(2)<<b[i]<<' '; cout<<fixed<<setprecision(2)<<b[lb-1]; return 0; }
1183:病人排队
#include<iostream> #include<algorithm> using namespace std; struct people { int xh,age; string id; } pp[100]; bool cmp(people x,people y) { if(x.age!=y.age&&(x.age>=60||y.age>=60))return x.age>y.age; return x.xh<y.xh; } int main() { int n; cin>>n; for(int i=0;i<n;i++) { pp[i].xh=i; cin>>pp[i].id>>pp[i].age; } sort(pp,pp+n,cmp); for(int i=0;i<n;i++)cout<<pp[i].id<<'\n'; }
1184:明明的随机数
#include<iostream> #include<algorithm> using namespace std; struct people { int xh,age; string id; } pp[100]; bool cmp(people x,people y) { if(x.age!=y.age&&(x.age>=60||y.age>=60))return x.age>y.age; return x.xh<y.xh; } int main() { int n; cin>>n; for(int i=0;i<n;i++) { pp[i].xh=i; cin>>pp[i].id>>pp[i].age; } sort(pp,pp+n,cmp); for(int i=0;i<n;i++)cout<<pp[i].id<<'\n'; }
1185:单词排序
using namespace std; #include<bits/stdc++.h> int main(){ string s,bs[101]; //char as[5000]; int n=0,f=0,l; while(getline(cin,s)) { f=0; l=s.size(); for(int i=0;i<=l;i++) { if(s[i]==' '||s[i]=='\0') { if(i>f) //如果不是连续空格就取出前一个字符串 bs[n++]=s.substr(f,i-f); f=i+1; //当前字符为空格,有效字符串只可能是下一位 开始 } } } //while(cin>>bs[f++]); sort(bs,bs+n);//相同单词应排在相邻位置 s=bs[0]; cout<<s; for(int i=1;i<n;i++) { if(bs[i]!=s)cout<<'\n'<<bs[i]; s=bs[i];//s用来记录每次输出的前一个单词,如果跟当单词一样就不输出 } cout<<endl; return 0; }
1186:出现次数超过一半的数
#include<iostream> using namespace std; int a[101]; int main(){ int n,t; cin>>n; for(int i=0;i<n;i++) { cin>>t; a[t+50]++; } for(int i=0;i<101;i++) if(a[i]>n/2) { cout<<i-50 ; return 0; } cout<<"no"; return 0; }
1187:统计字符数
#include<iostream> using namespace std; int a[26]; int main(){ string s; int ch,n,max,maxn=0; cin>>s; n=s.size() ; for(int i=0;i<n;i++) { ch=s[i]-'a'; a[ch]++; if(a[ch]>maxn||a[ch]==maxn&&ch<max)maxn=a[ch],max=ch; } cout<<char(max+'a')<<' '<<maxn; return 0; }
第三章 递推算法
1312:【例3.4】昆虫繁殖
#include<iostream> using namespace std; long long a[50]; int main(){ a[0]=1; int x,y,z; cin>>x>>y>>z; for(int i=1;i<x+2;i++)a[i]=1; for(int i=x+2;i<=z;i++)a[i]=a[i-1]+a[i-x-2]*y; cout<<a[z]; return 0; }
1313:【例3.5】位数问题
#include<iostream> using namespace std; int js[1001],os[1001]; int ws(int n) { js[1]=1,os[1]=8; for(int i=2;i<=n;i++) js[i]=(os[i-1]+js[i-1]*9)%12345,os[i]=(os[i-1]*9+js[i-1])%12345; return os[n]; } int main(){ int n; cin>>n; if(n==1)cout<<9; else cout<<ws(n); return 0; }
1314:【例3.6】过河卒(Noip2002)
#include<bits/stdc++.h> using namespace std; long long a[25][25];//(x,y)代表马的位置,(n,m)代表目标位置 //为方便输入马的控制位置,所有坐标均向右向下平移2单位 int main(){ std::ios::sync_with_stdio(false); int x,y,n,m; cin>>n>>m>>x>>y; for(int i=2;i<=n+2;i++) for(int j=2;j<=m+2;j++) a[i][j]=1; for(int i=0;i<=n+4;i++)a[i][1]=0; for(int j=0;j<=m+4;j++)a[1][j]=0; a[x][y+1]=a[x][y+3]=a[x+1][y]=a[x+1][y+4]=0; //对方马控制的8个点 a[x+3][y]=a[x+3][y+4]=a[x+4][y+1]=a[x+4][y+3]=0; //对方马控制的8个点 a[x+2][y+2]=0; a[2][1]=1; for(int i=2;i<=n+2;i++) for(int j=2;j<=m+2;j++) if(a[i][j]!=0)a[i][j]=a[i-1][j]+a[i][j-1]; cout<<a[n+2][m+2]; return 0; }
1188:菲波那契数列(2)
#include<iostream> using namespace std; int a[1000001],b[100]; int main(){ int n,max=0; cin>>n; for(int i=1;i<=n;i++) { cin>>b[i]; if(b[i]>max)max=b[i]; } a[1]=a[2]=1; for(int i=3;i<=max;i++) a[i]=(a[i-1]+a[i-2])%1000; for(int i=1;i<=n;i++)cout<<a[b[i]]<<'\n'; return 0; }
1189:Pell数列
#include<iostream> using namespace std; const int MAXN=1000005,M=32767; int fbnc[MAXN]; int fb(int n){ if(!fbnc[n])fbnc[n]=(fb(n-2)+2*fb(n-1))%M; return fbnc[n]; } int main(){ int n,x; fbnc[1]=1,fbnc[2]=2; cin>>n; for(int i=0;i<n;i++){ cin>>x; cout<<fb(x)<<endl; } return 0; }
1190:上台阶
#include<iostream> using namespace std; long long a[101]; int b[10000]; int main(){ int n=1,m,max=0; while(cin>>m&&m!=0) { b[n]=m; if(b[n++]>max)max=b[n-1]; } a[1]=1; a[2]=2; a[3]=4; for(int i=4;i<=max;i++) a[i]=a[i-1]+a[i-2]+a[i-3]; for(int i=1;i<n;i++)cout<<a[b[i]]<<'\n'; return 0; }
1191:流感传染
#include<iostream> using namespace std; int a[101][101]; int main(){ int n,num=0,m; char ch; cin>>n; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { cin>>ch; if(ch=='.')a[i][j]=1;//健康 else if(ch=='#')a[i][j]=0;//空 else a[i][j]=2,num++;//病人 } cin>>m; for(int i=2;i<=m;i++) for(int j=1;j<=n;j++) for(int k=1;k<=n;k++) { if(a[j][k]==2) { if(a[j-1][k]==1)a[j-1][k]=2,num++; if(a[j][k-1]==1)a[j][k-1]=2,num++; if(a[j+1][k]==1)a[j+1][k]=3,num++; if(a[j][k+1]==1)a[j][k+1]=3,num++; } if(a[j][k]==3)a[j][k]=2; } cout<<num; return 0; }
1192:放苹果
#include<iostream> using namespace std; int a[100][100],b[100][2]; long long fp1(int n,int m) { if(a[n][m])return a[n][m]; if(m==1||n==1||n==0)a[n][m]=1; else if(n<m)a[n][m]=fp1(n,n); else if(n>=m)a[n][m]=fp1(n,m-1)+fp1(n-m,m); return a[n][m]; } int main(){ int n; cin>>n; for(int i=1;i<=n;i++)cin>>b[i][0]>>b[i][1]; for(int i=1;i<=n;i++)cout<<fp1(b[i][0],b[i][1])<<endl; return 0; }
1193:吃糖果
#include<iostream> using namespace std; long long a[101]; int main(){ int n; cin>>n; a[1]=1; a[2]=2; for(int i=3;i<=n;i++) a[i]=a[i-1]+a[i-2]; cout<<a[n]<<'\n'; return 0; }
1194:移动路线
#include<iostream> using namespace std; int a[100][100]; int main(){ int n,m; cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(i==1||j==1)a[i][j]=1; else a[i][j]=a[i-1][j]+a[i][j-1]; cout<<a[n][m]; return 0; }
1195:判断整除
#include<iostream> using namespace std; int a[10001],b[10001][101],k,n; int main(){ cin>>n>>k; for(int i=1;i<=n;i++)cin>>a[i]; b[0][0]=1; for(int i=1;i<=n;i++) for(int j=0;j<k;j++) b[i][j]=b[i-1][(j+a[i]%k)%k]||b[i-1][(k+j-a[i]%k)%k]; if(b[n][0])cout<<"YES"; else cout<<"NO"; return 0; }
1196:踩方格
#include<iostream> using namespace std; int ans=0,a[30][50],fx[3][2]={{1,0},{0,-1},{0,1}}; void dfs(int x,int y,int p) { if(p<1)return; int tx,ty; a[x][y]=1;//表示己 for(int i=0;i<3;i++) { tx=x+fx[i][0],ty=y+fx[i][1]; if(a[tx][ty]==0) { if(p==1)ans++; dfs(tx,ty,p-1); a[tx][ty]=0; } } return; } int main() { int n; cin>>n; dfs(1,25,n); cout<<ans; return 0; }
1197:山区建小学
#include<iostream> #include<string.h> using namespace std; int dp[501][501],a[501],mi[501][501]; int m,n; int main() { int i,j,x,k; cin>>m>>n; a[1]=0; for (i=2;i<=m;i++) { cin>>x; a[i]=a[i-1]+x; } for (i=0;i<=m;i++) mi[i][i]=0; for (i=1;i<=m;i++) for (j=i+1;j<=m;j++) mi[i][j]=mi[i][j-1]+a[j]-a[(i+j)/2]; for (i=1;i<=m;i++) for (j=1;j<=n;j++) dp[i][j]=250000; for (i=1;i<=m;i++) dp[i][1]=mi[1][i]; for (i=2;i<=m;i++) for (j=2;j<=n;j++) for (k=j-1;k<i;k++) dp[i][j]=min(dp[i][j],dp[k][j-1]+mi[k+1][i]); cout<<dp[m][n]<<endl; return 0; }
第四章 递归算法
1315:【例4.5】集合的划分
#include<bits/stdc++.h> using namespace std; long long hs(int n,int m) { if(n<m)return 0; if(n==m)return 1; if(m==1)return 1; return hs(n-1,m-1)+m*hs(n-1,m); } int main() { int n,m; cin>>n>>m; cout<<hs(n,m); return 0; }
1316:【例4.6】数的计数(Noip2001)
#include<bits/stdc++.h> using namespace std; int a[1000]; int dfs(int n) { if(a[n]==0) { a[n]=1; for(int i=1;i<=n/2;i++) a[n]+=dfs(i); } return a[n]; } int main() { int n; cin>>n; a[1]=1; cout<<dfs(n); return 0; }
1198:逆波兰表达式
#include <bits/stdc++.h> using namespace std; double f[1000]; char s[1000]; double js() { cin>>s; if (s[0]=='*') return js()*js(); else if (s[0]=='/') return js()/js(); else if (s[0]=='-') return js()-js(); else if (s[0]=='+') return js()+js(); else return atof(s); } int main() { printf("%lf\n",js()); return 0; }
1199:全排列
#include<iostream> using namespace std; string s; int b[27],p[27],l; void pr() { for(int i=1;i<=l;i++) cout<<s[b[i]]; cout<<endl; return; } void dfs(int dp) { if(dp==l+1) { pr(); return; } for(int i=0;i<l;i++)//i为序号 { if(p[i]==0) { b[dp]=i; p[i]=1; dfs(dp+1); p[i]=0; } } } int main() { cin>>s; l=s.size() ; b[0]=-1; dfs(1); return 0; }
1200:分解因数
#include<iostream> using namespace std; int a[1000],ans; void fj(int x,int n) { ans++; for(int i=n;i<=x/i;i++) if(x%i==0)fj(x/i,i); return ; } int main() { int n; cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=n;i++) { ans=0; fj(a[i],2); cout<<ans<<endl; } return 0; }
1201:菲波那契数列
#include<iostream> using namespace std; int a[21],b[10000]; int main() { int n,max=0; cin>>n; for(int i=1;i<=n;i++) { cin>>b[i]; if(max<b[i])max=b[i]; } a[1]=1,a[2]=1; for(int i=3;i<=max;i++)a[i]=a[i-1]+a[i-2]; for(int i=1;i<=n;i++)cout<<a[b[i]]<<endl; return 0; }
1202:Pell数列
#include<iostream> using namespace std; int a[1000001],b[100]; int main() { int n,max=0; cin>>n; for(int i=1;i<=n;i++) { cin>>b[i]; if(max<b[i])max=b[i]; } a[1]=1,a[2]=2; for(int i=3;i<=max;i++)a[i]=(2*a[i-1]+a[i-2])%32767; for(int i=1;i<=n;i++)cout<<a[b[i]]<<endl; return 0; }
1203:扩号匹配问题
#include<bits/stdc++.h> using namespace std; char m[101][101]; char* pp(char arr[]) { char tmp[101]; char *ans=new char[101]; int t[101]; int l=strlen(arr),top=0; for(int i=0;i<l;i++) { ans[i]=' '; if(arr[i]=='(') tmp[++top]='(',t[top]=i; else if(arr[i]==')') if(tmp[top]=='(')top--; else ans[i]='?'; else ans[i]=' '; } while(top>0) { ans[t[top--]]='$'; } ans[l]='\0'; return ans; } int main() { int i=0; while(gets(m[i++])); for(int j=0;j<i;j++) { cout<<m[j]<<endl; cout<<pp(m[j])<<endl; } return 0; }
1204:爬楼梯
#include<iostream> using namespace std; int a[31],b[10001]; int main() { int n=0,maxn=0; while(cin>>b[n]) { if(maxn<b[n]) maxn=b[n]; n++; } a[1]=1,a[2]=2; for(int i=3;i<=maxn;i++) a[i]=a[i-1]+a[i-2]; for(int i=0;i<n;i++)cout<<a[b[i]]<<endl; return 0; }
1205:汉诺塔问题
#include<cstdio> void hnt(int n,char x,char y,char z) { if(n==1)printf("%c->1->%c\n",x,y); else { hnt(n-1,x,z,y); printf("%c->%d->%c\n",x,n,y); hnt(n-1,z,y,x); } } int main() { int n; char x,y,z; scanf("%d %c %c %c",&n,&x,&y,&z); hnt(n,x,y,z); return 0; }
1206:放苹果
#include<iostream> using namespace std; int a[100][100],b[100][2]; long long fp1(int n,int m) { if(a[n][m])return a[n][m]; if(m==1||n==1||n==0)a[n][m]=1; else if(n<m)a[n][m]=fp1(n,n); else if(n>=m)a[n][m]=fp1(n,m-1)+fp1(n-m,m); return a[n][m]; } int main(){ int n; cin>>n; for(int i=1;i<=n;i++)cin>>b[i][0]>>b[i][1]; for(int i=1;i<=n;i++)cout<<fp1(b[i][0],b[i][1])<<endl; return 0; }
1207:求最大公约数问题
#include<iostream> using namespace std; int main() { int n,m; cin>>n>>m; while(m) { int tmp=n; n=m; m=tmp%n; } cout<<n; return 0; }
1208:2的幂次方表示
#include<iostream> #include<cmath> using namespace std; string pp(int n) { if(n==1)return "2(0)"; if(n==2)return "2"; if(n==3)return "2+2(0)"; int p=0; while(n/2>=pow(2,p))p++; if(n==pow(2,p))return "2("+pp(p)+")"; else return "2("+pp(p)+")+"+pp(n-pow(2,p)); } int main() { int n; cin>>n; cout<<pp(n); return 0; }
1209:分数求和
#include<cstdio> using namespace std; int a[100][2]; int gcd(int n,int m) { while(m) { int tm=n; n=m; m=tm%n; } return n; } void plu(int &n,int &m,int x,int y) { n=n*y+x*m; int tmp=gcd(n,m*y); n/=tmp; m=m*y/tmp; } int main() { int n; scanf("%d",&n); for(int i=0;i<n;i++)scanf("%d/%d",&a[i][0],&a[i][1]); for(int i=1;i<n;i++)plu(a[0][0],a[0][1],a[i][0],a[i][1]); if(a[0][1]!=1)printf("%d/%d",a[0][0],a[0][1]); else printf("%d",a[0][0]); return 0; }
1210:因子分解
#include<iostream> using namespace std; int main() { int n,k=2,m,f=0; cin>>n; while(n>1) { m=0; while(n%k==0) { m++; n/=k; } if(m>=1) if(f==0) { cout<<k; f=1; } else cout<<"*"<<k; if(m>1)cout<<'^'<<m; k++; } return 0; }
1211:判断元素是否存在
#include<cstdio> int a[100001],a2[100001],a3[100001],t,t2=1,t3=1,h2=1,h3=1; int main(){ int n,x,tx2,tx3; scanf("%d,%d",&n,&x); a[0]=1,a2[0]=1,a3[0]=1; while(a[t]<x) { a2[t2++]=2*a[t]+1,a3[t3++]=3*a[t]+1; t++; if(a2[h2]<a3[h3])a[t]=a2[h2++]; else if(a2[h2]>a3[h3])a[t]=a3[h3++]; else { a[t]=a2[h2++]; h3++; } } if(a[t]==x)printf("YES"); else printf("NO"); return 0; }
第五章 搜索与回溯算法
1317:【例5.2】组合的输出
#include<iostream> #include<iomanip> using namespace std; int n,r,a[21]; void pr() { for(int i=1;i<=r;i++)cout<<fixed<<setw(3)<<a[i]; cout<<endl; return; } void dfs(int star,int dp) { //边界 if(dp==r+1) { pr(); return; } //递推 for(int i=star;i<=n;i++) { a[dp]=i; star=i+1; dfs(star,dp+1); } } int main() { cin>>n>>r; dfs(1,1); return 0; }
1318:【例5.3】自然数的拆分
#include<bits/stdc++.h> using namespace std; int a[10001],n; void print(int step) { cout<<n<<"="; for(int i=1;i<step;i++) cout<<a[i]<<"+"; cout<<a[step]<<endl; } void dfs(int c,int step) { for(int i=a[step-1];i<=c;i++) { if(i<n) { a[step]=i; c=c-i; if(c==0) print(step); else dfs(c,step+1); c=c+i; } } } int main() { for(int i=0;i<1001;i++) a[i]=1; cin>>n; dfs(n,1); return 0; }
1212:LETTERS
#include<iostream> #include<cstdio> using namespace std; int a[22][22],b[27],ans=0; int fx[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; void dfs(int x,int y,int dp) { int tx,ty; if(dp>ans)ans=dp; b[a[x][y]]=1; for(int i=0;i<4;i++) { tx=x+fx[i][0]; ty=y+fx[i][1]; if(b[a[tx][ty]]==0) { dfs(tx,ty,dp+1); b[a[tx][ty]]=0; } } } int main(){ int r,c; char ch; scanf("%d %d",&r,&c); for(int i=1;i<=r;i++) for(int j=1;j<=c;j++) { cin>>ch; a[i][j]=ch-'A'+1; } b[0]=1; dfs(1,1,1); printf("%d",ans); return 0; }
1213:八皇后问题
#include<iostream> #include<iomanip> using namespace std; int b[9],ans=1; void pr() { cout<<"No. "<<ans++<<endl; for(int i=1;i<9;i++) { for(int j=1;j<9;j++) { if(b[j]==i)cout<<1; else cout<<0; if(j<8)cout<<' '; } cout<<endl; } } bool jc(int n,int y) { for(int i=1;i<n;i++) { if(b[i]==y)return false; if(i+b[i]==n+y)return false; if(i-b[i]==n-y)return false; } return true; } void qk(int n) { if(n==9)pr(); for(int i=1;i<9;i++) { if(jc(n,i)) { b[n]=i; qk(n+1); b[n]=0; } } return; } int main(){ qk(1); return 0; }
1214:八皇后
#include<iostream> #include<iomanip> using namespace std; int b[9],ans=0,a[93],c[1000]; bool jc(int n,int y) { for(int i=1;i<n;i++) { if(b[i]==y)return false; if(i+b[i]==n+y)return false; if(i-b[i]==n-y)return false; } return true; } void qk(int n) { if(n==9) { ans++; int num=0; for(int i=1;i<9;i++)num=num*10+b[i]; a[ans]=num; return; } for(int i=1;i<9;i++) { if(jc(n,i)) { b[n]=i; qk(n+1); b[n]=0; } } return; } int main(){ qk(1); int n; cin>>n; for(int i=1;i<=n;i++)cin>>c[i]; for(int i=1;i<=n;i++)cout<<a[c[i]]<<endl; return 0; }
1215:迷宫
#include<iostream> #include<cstring> using namespace std; int a[102][102],b[1000],n,ha,la,hb,lb,m; int fx[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; int dfs(int x,int y) { if(x==hb&&y==lb)return 1; a[x][y]=0; int tx,ty; for(int i=0;i<4;i++) { tx=x+fx[i][0]; ty=y+fx[i][1]; if(a[tx][ty]) if(dfs(tx,ty))return 1; } return 0; } int main(){ cin>>n; char ch; for(int i=1;i<=n;i++) { cin>>m; memset(a,0,sizeof(a)); for(int j=1;j<=m;j++) for(int k=1;k<=m;k++) { cin>>ch; if(ch=='.')a[j][k]=1; } cin>>ha>>la>>hb>>lb; ha++,la++,hb++,lb++; if(a[ha][la]==0||a[hb][lb]==0)b[i]=0; else b[i]=dfs(ha,la); } for(int i=1;i<=n;i++) { if(b[i])cout<<"YES\n"; else cout<<"NO\n"; } return 0; }
1216:红与黑
#include<iostream> #include<cstring> using namespace std; int a[102][102],b[1000],l,n,ha,la,m,ans; int fx[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; void dfs(int x,int y) { ans++; a[x][y]=0; int tx,ty; for(int i=0;i<4;i++) { tx=x+fx[i][0]; ty=y+fx[i][1]; if(a[tx][ty])dfs(tx,ty); } return; } int main(){ do { cin>>m>>n; if(m==0&&n==0)break; char ch; ans=0; memset(a,0,sizeof(a)); for(int j=1;j<=n;j++) for(int k=1;k<=m;k++) { cin>>ch; if(ch=='.')a[j][k]=1; if(ch=='@')ha=j,la=k; } dfs(ha,la); b[l++]=ans; }while(1); for(int i=0;i<l;i++)cout<<b[i]<<'\n'; return 0; }
1217:棋盘问题
#include<iostream> #include<cstring> using namespace std; int a[102][102],b[1000],c[10][2],l,n,m,ans; bool check(int y,int p) { for(int i=1;i<p;i++) if(c[i][1]==y)return false; return true; } void dfs(int h,int dp) { if(dp==m+1) { ans++; return; } for(int i=h;i<=n;i++) for(int j=1;j<=n;j++) { if(check(j,dp)&&a[i][j]) { c[dp][0]=i,c[dp][1]=j; dfs(i+1,dp+1); c[dp][0]=0,c[dp][1]=0; } } return; } int main(){ do { cin>>n>>m; if(m==-1&&n==-1)break; char ch; ans=0; memset(a,0,sizeof(a)); memset(c,0,sizeof(c)); for(int j=1;j<=n;j++) for(int k=1;k<=n;k++) { cin>>ch; if(ch=='#')a[j][k]=1; } dfs(1,1); b[l++]=ans; }while(1); for(int i=0;i<l;i++)cout<<b[i]<<'\n'; return 0; }
1218:取石子游戏
#include<iostream> using namespace std; int a[10000],l; int main(){ int n,m; do { cin>>n>>m; if(!(n|m))break; if(n<m)swap(n,m); if(n/m>=2||n%m==0)a[l++]=1; else { int k=1; while(n/m<2&&n%m) { int tmp=m; m=n%m; n=tmp; k++; } if(k%2)a[l++]=1; else a[l++]=0; } }while(1); for(int i=0;i<l;i++) if(a[i])cout<<"win\n"; else cout<<"lose\n"; return 0; }
1219:马走日
#include<bits/stdc++.h> using namespace std; int f[8][2]={{1,-2},{2,-1},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2}}; int a[11][11]; int T; int n,m,x,y; int ans; void research(int x,int y,int dep) { if(dep==n*m) { ans++; return; } else { for(int i=0;i<8;i++) { int x1=x+f[i][0]; int y1=y+f[i][1]; if(x1>=1&&x1<=n&&y1>=1&&y1<=m&&a[x1][y1]==0) { a[x1][y1]=1; research(x1,y1,dep+1); a[x1][y1]=0; } } } } int main() { cin>>T; for(int i=1;i<=T;i++) { memset(a,0,sizeof(a)); ans=0; cin>>n>>m>>x>>y; x++;y++; a[x][y]=1; research(x,y,1); printf("%d\n",ans); } return 0; }
1220:单词接龙
#include<bits/stdc++.h> using namespace std; string ss[1001],ms; int p[1001],maxn,n; bool kjl(string s1,string s2,int n) { int l1=s1.size(),l2=s2.size(); if(n>l1||n>l2)return false; for(int i=0;i<n;i++) if(s1[l1-1-i]!=s2[n-1-i])return false; return true; } int jl(string s1,string s2) { int l1=s1.size(),l2=s2.size(); for(int i=1;i<l1&&i<l2;i++) if(kjl(s1,s2,i))return i; return 0; } void dfs(string s) { int l1=s.size(); if(maxn<l1)maxn=l1; for(int i=1;i<=n;i++) { int tt= jl(s,ss[i]); if(p[i]<2&&tt>0) { p[i]++; dfs(s.substr(0,l1-tt)+ss[i]); p[i]--; } } } int main() { char ch; cin>>n; for(int i=1;i<=n;i++)cin>>ss[i]; cin>>ch; for(int i=1;i<=n;i++) if(ss[i][0]==ch) { p[i]=1; dfs(ss[i]); p[i]=0; } cout<<maxn; return 0; }
1221:分成互质组
#include<iostream> using namespace std; int n,a[100],b[100][100],c[100],ans=1; int gcd(int n,int m) { while(m) { int mp=n; n=m; m=mp%n; } return n; } int main() { cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; b[1][1]=a[1]; c[1]=1; for(int i=2;i<=n;i++) { int ok; for(int j=1;j<=ans;j++) { ok=1; for(int k=1;k<=c[j];k++) if(gcd(b[j][k],a[i])>1) { ok=0; break; } if(ok) { c[j]++; b[j][c[j]]=a[i]; break; } } if(ok==0) { ans++; b[ans][1]=a[i]; c[ans]=1; } } cout<<ans; return 0; }
1222:放苹果
#include<iostream> using namespace std; int a[100][100],b[100][2]; long long fp1(int n,int m) { if(a[n][m])return a[n][m]; if(m==1||n==1||n==0)a[n][m]=1; else if(n<m)a[n][m]=fp1(n,n); else if(n>=m)a[n][m]=fp1(n,m-1)+fp1(n-m,m); return a[n][m]; } int main(){ int n; cin>>n; for(int i=1;i<=n;i++)cin>>b[i][0]>>b[i][1]; for(int i=1;i<=n;i++)cout<<fp1(b[i][0],b[i][1])<<endl; return 0; }
第六章 贪心算法
1319:【例6.1】排队接水
#include<bits/stdc++.h> using namespace std; int a[1010],b[1010],n; int sum=0,num; int main() { int t; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; b[i]=i; } for(int i=1;i<=n-1;i++) for(int j=1;j<=n-i;j++) { if(a[j]>a[j+1]) { swap(a[j],a[j+1]); swap(b[j],b[j+1]); } } for(int i=1;i<=n;i++) { num=0; for(int j=i-1;j>=1;j--) { num=num+a[j]; } sum=sum+num; } for(int i=1;i<=n;i++) printf("%d ",b[i]); printf("\n%.2f",1.0*sum/n); return 0; }
1320:【例6.2】均分纸牌(Noip2002)
#include<iostream> using namespace std; int a[105]; int num=10000,ans=0; int main() { int n,sum=0,w; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; sum+=a[i]; } int b=sum/n; for(int i=1;i<=n;i++) { if(a[i]==b) continue; else { w=a[i]-b; a[i+1]+=w; ans++; } } cout<<ans; return 0; }
1321:【例6.3】删数问题(Noip1994)
#include<cstring> #include<iostream> #include<cstdio> using namespace std; int st[250],p[250]; int main() { string s; int cn,on=0,hn=0,tn=1,f=0; cin>>s>>cn; //on表示已经删除的数字个数 for(int i=0;i<s.size();i++)st[i]=s[i]-'0',p[i]=1; while(tn<s.size()) { if(st[hn]>st[tn]) { p[hn]=0; on++; if(on==cn)break; while(hn>=0&&p[hn]==0)hn--; if(hn<0)hn=tn,tn++; } else hn=tn,tn++; } on=0;//on表示已经输出的数字个数(前导零不输出,但要算一个输出数字) for(int i=0;i<s.size();i++) { if(p[i]) { if(st[i]!=0)f=1;//遇到第一个非零数字即表示可以开始输出 if(f)cout<<st[i]; on++; if(on==s.size()-cn)break; } } return 0; }
1322:【例6.4】拦截导弹问题(Noip1999)
#include<iostream> #include<cstring> #define MAXN 1000 using namespace std; int a[MAXN+10];//导弹飞来时的高度 int l[MAXN+10];//拦截导弹最低高度 int main() { memset(a,0,sizeof(a)); memset(l,0,sizeof(l)); int n=1; while(cin>>a[n]) { n++; } int k=1;//拦截导弹系统数 int p,j=1; l[k]=a[1]; for(int i=2;i<=n;i++) { p=0;//注意每次循环时需要p=0 for(int j=1;j<=k;j++)//注意,j<=k { if(l[j]>=a[i]) { if(p==0) p=j; else if(l[p]>l[j]) p=j;//如果同时满足例如l[1]=155>65,l[2]=158>65,则应该应将最小值赋值给最小拦截系统 } } if(p==0) { k++;//如果发现a[i]>l[j],则应该增加一个系统 l[k]=a[i];//更新新系统的最小值 } else l[p]=a[i];//更新原系统的拦截最小值 } cout<<k<<endl; return 0; }
1323:【例6.5】活动选择
#include<bits/stdc++.h> using namespace std; struct huodong { int b; int e; int num; } a[1010]; int main() { int n; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i].b>>a[i].e; a[i].num=i; } for(int i=1;i<=n-1;i++) for(int j=1;j<=n-i;j++) { if(a[j].e>a[j+1].e) swap(a[j],a[j+1]); } int min=a[1].e; int coutt=1; for(int i=2;i<=n;i++) { if(a[i].b>=min) { coutt++; min=a[i].e; } } cout<<coutt<<endl; return 0; }
1324:【例6.6】整数区间
#include<iostream> #include<algorithm> using namespace std; struct qj{ int l,r; }a[10001]; bool cmp(qj x,qj y) { return x.r<y.r; } int main() { int n; cin>>n; for(int i=1;i<=n;i++)cin>>a[i].l>>a[i].r; sort(a+1,a+n+1,cmp); int x=-1,ans=0; for(int i=1;i<=n;i++) { if(a[i].l>x) { x=a[i].r; ans++; } } cout<<ans; return 0; }
1223:An Easy Problem
#include<iostream> using namespace std; int a[100],b[10000],n,nn; int t(int x) { int xn=0; while(x) { if(x%2)xn++; x/=2; } return xn; } int main(){ int x; while(cin>>x&&x) { n=t(x); int tmp=x+1; while(t(tmp)!=n)tmp++; b[nn++]=tmp; } for(int i=0;i<nn;i++)cout<<b[i]<<endl; return 0; }
1224:最大子矩阵
#include <iostream> #include <cstring> using namespace std; const int maxn =101; int n,m,res=-127; int a[maxn][maxn],b[maxn],dp[maxn]; int main() { cin>>n; m=n; for(int i=0;i<n;i++) for(int j=0;j<m;j++) cin>>a[i][j]; for(int x=0;x<n;x++){//设置起始行 memset(b,0,sizeof(b));//设置结束行 for(int y=x;y<n;y++) { for(int j=0;j<m;j++) b[j]+=a[y][j];//b存储第起始行x到y行到中每一列的值 dp[0]=b[0]; if(dp[0]>res)//不要忘了这个 res=dp[0]; for(int i=1;i<m;i++) { if(dp[i-1]<0) dp[i]=b[i]; else dp[i]=dp[i-1]+b[i]; if(dp[i]>res) //维护最后的结果 res=dp[i]; } } } cout<<res<<endl; return 0; }
1225:金银岛
//1225:金银岛 #include<iostream> #include<algorithm> #include<iomanip> using namespace std; struct bb{ int t,v; double bl; void bin() { cin>>t>>v; bl=1.0*v/t; } }a[10001]; bool cmp(bb x,bb y) { return x.bl>y.bl; } int main() { int t,w,n; double ans; cin>>t; for(int i=1;i<=t;i++) { ans=0; cin>>w>>n; for(int j=1;j<=n;j++)a[j].bin(); sort(a+1,a+n+1,cmp); for(int j=1;j<=n&&w>0;j++) { if(a[j].t<=w) { w-=a[j].t; ans+=a[j].v; } else { ans+=a[j].bl*w; w=0; } } cout<<fixed<<setprecision(2)<<ans<<endl; } return 0; }
1226:装箱问题
#include<bits/stdc++.h> using namespace std; int main() { int n,a,b,c,d,e,f,x,y; int u[4]={0,5,3,1}; while(1){ scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&e,&f); if(a==0&&b==0&&c==0&&d==0&&e==0&&f==0) break; n=d+e+f+(c+3)/4; y=5*d+u[c%4]; if(b>y) n+=(b-y+8)/9; x=36*n-36*f-25*e-16*d-9*c-4*b; if(a>x) n+=(a-x+35)/36; cout<<n<<endl; } return 0; }
1227:Ride to Office
//1227:Ride to Office //这个题没给速度和时间单位,根据样例数据只能理解为时间为秒,速度单位为公里/小时 #include<iostream> #include<cmath> using namespace std; int const N=1e4+2; int n,ans,t,v; int main(){ while(cin>>n&&n) { ans=1e5; for(int i=1;i<=n;i++) { cin>>v>>t; if(t>=0&&16200.0/v+t<ans)ans=ceil(16200.0/v+t); } cout<<ans<<endl; } return 0; }
1228:书架
//1228:书架 #include<iostream> #include<algorithm> using namespace std; typedef long long ll; int hi[20001],sum[20001]; bool cmp(ll x,ll y) { return x>y; } int main() { int n,b; cin>>n>>b; for(int i=1;i<=n;i++)cin>>hi[i]; sort(hi+1,hi+n+1,cmp); for(int i=1;i<=n;i++)sum[i]=sum[i-1]+hi[i]; int l=1,r=n; while(l<r) { int m=(l+r)>>1; if(sum[m]>=b)r=m; else l=m+1; } cout<<r; return 0; }
1229:电池的寿命
//1229:电池的寿命 #include<iostream> #include<iomanip> using namespace std; int n, a[1001]; int main(){ int mx,mn,sm; while(cin>>n) { mx=sm=0; mn=1e8; for(int i=0;i<n;i++) { cin>>a[i]; if(a[i]>mx)mx=a[i]; if(a[i]<mn)mn=a[i]; sm+=a[i]; } if(2==n)cout<<fixed<<setprecision(1)<<mn*1.0<<endl; else if(sm<mx*2)cout<<fixed<<setprecision(1)<<1.0*sm-mx<<endl; else cout<<fixed<<setprecision(1)<<sm/2.0<<endl; } return 0; }
1230:寻找平面上的极大点
//1230:寻找平面上的极大点 #include<iostream> using namespace std; int a[101];//存以x为坐标的所有点的最大纵坐标,对应点(x,a[x])即为极 int main(){ int n,x,y,f=0,mx=0; cin>>n; for(int i=1;i<=n;i++) { cin>>x>>y; if(a[x]<y)a[x]=y; } for(int i=100;i>=0;i--) { if(a[i]>mx)mx=a[i]; else a[i]=0; } for(int i=0;i<=100;i++) { if(!a[i])continue; if(f)cout<<','; cout<<'('<<i<<','<<a[i]<<')'; f=1; } return 0; }
1231:最小新整数
//1231:最小新整数 int a[10],p[10]; #include<iostream> #include<cstring> using namespace std; int main(){ int n,num,k,len; cin>>n; for(int i=1;i<=n;i++) { memset(p,0,sizeof(p)); len=0; cin>>num>>k; while(num) { a[++len]=num%10; num/=10; } int l=len,r=len-1,sl=0; while(sl<k&&r>=1) { if(a[l]>a[r]) { p[l]=1; sl++; while(p[l])l++; } else l=r,r--; if(l==len+1)l=r,r--; } sl=0; for(int j=len;j>=1&&sl<len-k;j--) { while(p[j])j--; cout<<a[j]; sl++; } cout<<endl; } return 0; }
1232:Crossing River
//1232:Crossing River #include<iostream> #include<algorithm> using namespace std; int const N=1e5+2; int a[N],n,m,ans; int main(){ cin>>m; while(m--) { cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; sort(a+1,a+n+1); ans=0; while(n>3) { if(a[n]+a[2]*2+a[1]<a[n]+a[n-1]+a[1]*2)ans+=a[n]+a[2]*2+a[1]; else ans+=a[n]+a[n-1]+a[1]*2; n-=2; } if(n==3)ans+=a[3]+a[1]+a[2]; if(n==2)ans+=a[2]; if(n==1)ans=a[1]; cout<<ans<<endl; } return 0; }
1233:接水问题
//1233:接水问题 #include<iostream> using namespace std; int ans,n,m,a[1000001]; long long b[1000001]; int main(){ cin>>n>>m; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=m;i++) if(i<=n)b[i]=a[i]; else b[i]=0; for(int i=m+1;i<=n;i++) { int k=1,minx=b[1]; for(int j=2;j<=m;j++) if(b[j]<minx)minx=b[j],k=j; b[k]+=a[i]; } ans=b[1]; for(int i=2;i<=m;i++) if(ans<b[i])ans=b[i]; cout<<ans<<endl; return 0; }
第七章 分治算法
1325:【例7.4】 循环比赛日程表
#include<iostream> using namespace std; int sc[130][130],n; void makelist(int fx,int fy,int lx,int ly,int fn,int ln){ if(fn==ln)sc[fx][fy]=fn; else { int tmpx=(fx+lx)/2,tmpy=(fy+ly)/2,tmpn=(fn+ln)/2; makelist(fx,fy,tmpx,tmpy,fn,tmpn); makelist(fx,tmpy+1,tmpx,ly,tmpn+1,ln); makelist(tmpx+1,fy,lx,tmpy,tmpn+1,ln); makelist(tmpx+1,tmpy+1,lx,ly,fn,tmpn); } } void printlist(int n){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++)cout<<sc[i][j]<<' '; cout<<endl; } } int main(){ cin>>n; n=1<<n; makelist(1,1,n,n,1,n); printlist(n); return 0; }
1326:【例7.5】 取余运算(mod)
#include<iostream> using namespace std; long b,p,k; long mmod(long b,long p,long k) { if(p==1)return b%k; long long t=mmod(b,p/2,k); t=t*t%k; if(p%2)t=t*b%k; return long(t); } int main(){ cin>>b>>p>>k; cout<<b<<'^'<<p<<" mod "<<k<<'='<<mmod(b,p,k); return 0; }
1327:【例7.6】黑白棋子的移动
#include<cstdio> char ch[10000]; int n,h; void pr() { printf("step%2d:",h++); for(int i=0;i<=2*n+1;i++) printf("%c",ch[i]); printf("\n"); return; } void move(int x,int y) { ch[y]=ch[x],ch[y+1]=ch[x+1]; ch[x]=ch[x+1]='-'; return; } int main(){ scanf("%d",&n); for(int i=0;i<n;i++)ch[i]='o'; for(int i=n;i<2*n;i++)ch[i]='*'; ch[2*n]=ch[2*n+1]='-'; pr(); for(int i=0;i<n-4;i++) { move(n-1-i,2*(n-i)); pr(); move(2*(n-i-1),n-1-i); pr(); } move(3,8); pr(); move(7,3); pr(); move(1,7); pr(); move(6,1); pr(); move(0,6); pr(); return 0; }
1328:【例7.7】光荣的梦想
//1328:【例7.7】光荣的梦想 #include<iostream> using namespace std; int n,a[10001],ans; int main(){ cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<n;i++) for(int j=1;j<=n-i;j++) { if(a[j]>a[j+1]) { int t=a[j+1]; a[j+1]=a[j]; a[j]=t; ans++; } } cout<<ans<<endl; //for(int i=1;i<=n;i++)cout<<a[i]<<' '; return 0; }
1234:2011
#include<iostream> using namespace std; int a[200][10],b[200][200],mx; int js(int base,int n) { if(n==1)return base; if(n%2)return js(base,n-1)*base%10000; else return js(base,n/2)*js(base,n/2)%10000; } void ini() { a[0][1]=2011,a[0][0]=1; for(int i=2;i<10;i++)a[0][i]=a[0][i-1]*2011%10000; for(int i=1;i<mx;i++) for(int j=0;j<10;j++) { if(j==0)a[i][j]=1; else if(j==1)a[i][j]=a[i-1][9]*a[i-1][1]%10000; else a[i][j]=a[i][j-1]*a[i][1]%10000; } } int js2(int x,int n) { int i=0,ans=1; while(i<n) { ans*=a[i][b[x][i+1]]; ans%=10000; i++; } return ans; } int main(){ int n,l; string s; cin>>n; for(int i=0;i<n;i++) { cin>>s; l=s.size(); if(l>mx)mx=l; b[i][0]=l; for(int j=1;j<=l;j++) b[i][j]=s[l-j]-'0'; } ini(); for(int i=0;i<n;i++)cout<<js2(i,b[i][0])<<endl; return 0; }
1235:输出前k大的数
//1235:输出前k大的数 #include<cstdio> int const N=1e5+1; int a[N],n,k; void qs(int low,int high) { int l=low,h=high; int key=a[l]; while(l<h) { while(l<h&&a[h]>=key)h--; a[l]=a[h]; while(l<h&&a[l]<=key)l++; a[h]=a[l]; } a[l]=key; if(l>n-k+1&&low<l-1)qs(low,l-1); if(high>l+1)qs(l+1,high); } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",a+i); scanf("%d",&k); qs(1,n); while(k--)printf("%d\n",a[n--]); return 0; }
1236:区间合并
//1236:区间合并 #include<iostream> #include<algorithm>//排序函数调用 using namespace std; int const N=5e4+1; struct qj{ int l,r; bool operator < (qj const x){ if(l<x.l||l==x.l&&r<x.r)return true; else return false; } }a[N]; int n,x,y; int main(){ cin>>n; for(int i=1;i<=n;i++)cin>>a[i].l>>a[i].r; sort(a+1,a+n+1); x=a[1].l,y=a[1].r; for(int i=2;i<=n;i++) if(a[i].l>y) { cout<<"no"; return 0; } else if(a[i].r>y)y=a[i].r; cout<<x<<' '<<y<<endl; return 0; }
1237:求排列的逆序数
//1237:求排列的逆序数 #include<iostream> using namespace std; int const N=1e5+1; int a[N],b[N],n; long long ans; void gb(int low,int high) { if(low>=high)return; int l=low,r=high,m=(low+high)/2; gb(l,m); gb(m+1,r); int i=l,j=m+1,k=l; while(i<=m&&j<=r) if(a[i]<=a[j])b[k++]=a[i++]; else b[k++]=a[j++],ans+=m-i+1; while(i<=m)b[k++]=a[i++]; while(j<=r)b[k++]=a[j++]; for(i=l;i<=r;i++)a[i]=b[i]; } int main(){ ios::sync_with_stdio(false); cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; gb(1,n); //for(int i=1;i<=n;i++)cout<<a[i]<<' '; cout<<ans<<endl; return 0; }
1238:一元三次方程求解
//1238:一元三次方程求解 #include<iostream> #include<iomanip> using namespace std; int k; double ans[3],a,b,c,d,x0=-101; int f(double x) { double y; y=a*x+b; y=x*y+c; y=x*y+d; if(-y>1e-12)return -1; else if(y>1e-12)return 1; else return 0; } double f1(double x) { double y; y=a*x+b; y=x*y+c; y=x*y+d; return y; } double key(double x,double y) { //cout<<'['<<x<<','<<y<<']'; double m=(x+y)/2; if(y-x<0.0005||f(m)==0)return m; if(f(x)*f(m)==1)return key(m,y); else return key(x,m); } int main(){ cin>>a>>b>>c>>d; for(double i=-100;i<=100;i+=0.5) if(f(i)==0) { ans[k++]=i; x0=i+0.5; if(k==3)break; } else if(f(x0)*f(i)==1)x0=i; else { ans[k++]=key(x0,i); x0=i; if(k==3)break; } for(int i=0;i<3;i++) cout<<fixed<<setprecision(2)<<ans[i]<<' '; return 0; }
1239:统计数字
//1239:统计数字 #include<iostream> using namespace std; int const inf=2e9; int n,a[20001],b[20001],x,cnt,p; int pos(int x,int l,int r) { int m=(l+r)/2; if(r-l==2)return m; if(m%2)m--; if(x==a[m])return m; if(x<a[m])return pos(x,l,m); return pos(x,m,r); } int main(){ ios::sync_with_stdio(false); a[0]=-1,a[2]=inf; cin>>n; for(int i=1;i<=n;i++) { cin>>x; p=pos(x,0,cnt+2); if(p%2) { cnt+=2; for(int j=cnt+2;j>p+1;j-=2)a[j]=a[j-2],b[j]=b[j-2]; a[p+1]=x,b[p+1]=1; } else b[p]++; } for(int i=2;i<=cnt;i+=2)cout<<a[i]<<' '<<b[i]<<endl; return 0; }
1240:查找最接近的元素
//1240:查找最接近的元素 #include<iostream> using namespace std; int a[100000],n,m,q,ans[10001]; int main(){ cin>>n; for(int i=0;i<n;i++)cin>>a[i]; cin>>m; for(int i=0;i<m;i++) { cin>>q; if(q<=a[0]) { ans[i]=a[0]; continue; } if(q>=a[n-1]) { ans[i]=a[n-1]; continue; } int l=0,r=n-1,mid; while(l<r-1) { mid=(l+r)>>1; if(a[mid]==q) { ans[i]=mid; l=r=mid; } else if(a[mid]>q)r=mid; else l=mid; } if(a[l]+a[r]>=q*2)ans[i]=a[l]; else ans[i]=a[r]; } for(int i=0;i<m;i++)cout<<ans[i]<<endl; return 0; }
1241:二分法求函数的零点
//1241:二分法求函数的零点 #include<iostream> #include<iomanip> using namespace std; double a[6]={1},b[6]={-121,274,-225,85,-15,1}; void fc(double x) { for(int i=1;i<=5;i++) a[i]=a[i-1]*x; return; } double f(double x) { double t=0; fc(x); for(int i=0;i<6;i++)t+=a[i]*b[i]; if(t>1e-12)return 1; else if(t<-1e-12)return -1; return 0; } int main() { double l=1.5,r=2.4,mid; while(r-l>1e-8) { mid=(l+r)/2; //cout<<l<<' '<<r<<' '<<f(mid)<<' '<<mid<<endl; if(f(mid)==1)l=mid; else if(f(mid)==-1)r=mid; else break; } cout<<fixed<<setprecision(6)<<mid; return 0; }
1242:网线主管
//1242:网线主管 #include<iostream> #include<iomanip> using namespace std; int const N=1e4+1; long long b[N],ans,n,s; double t; long long ts(int x) { long long int num=0; for(int i=1;i<=n;i++)num+=b[i]/x; return num; } int f(int l,int r) { int m=(l+r)/2; if(r-l<=1)return l; if(ts(m)>=s)return f(m,r); else return f(l,m); } int main(){ cin>>n>>s; for(int i=1;i<=n;i++) { cin>>t; b[i]=t*100+0.1; } if(ts(1)<s)ans=0; else if(ts(1e8)>=s)ans=1e8; else ans=f(1,1e8); cout<<fixed<<setprecision(2)<<ans/100.0+0.0001; return 0; }
1243:月度开销
//1243:月度开销 #include<iostream> using namespace std; int const N=1e5+1; int a[N],s[N],n,m,max1,maxn; bool tj(int x) { int cnt=1,ts=0; for(int i=1;i<=n;i++) if(ts+a[i]<=x)ts+=a[i]; else ts=a[i],cnt++; return cnt<=m; } int main(){ cin>>n>>m; for(int i=1;i<=n;i++) { cin>>a[i]; s[i]=s[i-1]+a[i]; if(max1<a[i])max1=a[i]; } maxn=s[n-m]; for(int i=n-m+1;i<=n;i++) if(maxn<s[i]-s[i-n+m])maxn=s[i]-s[i-n+m]; int l=max1-1,r=2e9; while(l+1<r) { int mm=(l+r)/2; if(tj(mm))r=mm; else l=mm; } cout<<r; return 0; }
1244:和为给定数
//1244:和为给定数 #include<iostream> #include<algorithm> using namespace std; int const N=1e5+1; int a[N],n,m; int main(){ cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; cin>>m; sort(a+1,a+n+1); int i=1,j=n; while(i<j) { if(a[i]+a[j]==m)break; else if(a[i]+a[j]<m)i++; else j--; } if(i<j)cout<<a[i]<<' '<<a[j]; else cout<<"No"; return 0; }
1245:不重复地输出数
//1245:不重复地输出数 #include<iostream> #include<algorithm> using namespace std; int const N=1e5+1; int a[N],n; int main(){ cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; sort(a+1,a+1+n); int x=a[1]; cout<<x; for(int i=2;i<=n;i++) if(a[i]!=x) { cout<<' '<<a[i]; x=a[i]; } return 0; }
1246:膨胀的木棍
//1246:膨胀的木棍 #include<iostream> #include<iomanip> #include<cmath> using namespace std; int main(){ double l,d,c,n,r,alf,x; cin>>d>>n>>c; l=d*(1+n*c); //解方程lsing(alf) =alf*d double m=0;n=acos(-1.0)/2; while(n-m>1e-12) { double b=(m+n)/2; if(l*sin(b)>b*d)m=b; else if(l*sin(b)<b*d)n=b; } alf=m; r=l/alf/2; x=r-r*cos(alf); cout<<fixed<<setprecision(3)<<x; return 0; }
1247:河中跳房子
//1247:河中跳房子 #include<iostream> using namespace std; int const N=5e4+2; int s[N],a[N],l,n,m; bool ts(int x) { int jl=0,cnt=0; for(int i=1;i<=n;i++) if(l-s[i]<x)cnt+=n+1-i,i=n+1; else if(jl+a[i]<x)cnt++,jl+=a[i]; else jl=0; return cnt<=m; } int main(){ cin>>l>>n>>m; for(int i=1;i<=n;i++) { cin>>s[i]; a[i]=s[i]-s[i-1]; } int low=1,high=l; while(low+1<high) { int mid=(low+high)/2; if(ts(mid))low=mid; else high=mid; } cout<<low; return 0; }
第八章 广度优先搜索算
1329:【例8.2】细胞
#include<iostream> using namespace std; int n,m,ans,tmp,a[110][110],que[110*110][2]; int fx[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; void bfs(int x,int y){ int head=0,tail=1,curx,cury; que[0][0]=x,que[0][1]=y; while(head<tail){ curx=que[head][0]; cury=que[head++][1]; for(int i=0;i<4;i++){ int tmpx=curx+fx[i][0]; int tmpy=cury+fx[i][1]; if(a[tmpx][tmpy]) { que[tail][0]=tmpx; que[tail++][1]=tmpy; a[tmpx][tmpy]=0; } } } } int main(){ //freopen("blacks.in","r",stdin); cin>>n>>m; char ch; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>ch; if(ch>'0')a[i][j]=1; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]){ ++ans; bfs(i,j); } cout<<ans<<endl; return 0; }
1330:【例8.3】最少步数
#include<iostream> using namespace std; int a[104][104],num[104][104],que[10000][2],ha,la,hb,lb,ans1,ans2; int dx[12]={2,2,2,2,1,1,-1,-1,-2,-2,-2,-2}; int dy[12]={2,1,-1,-2,2,-2,2,-2,2,1,-1,-2}; void bfs() { int h=0,t=1,cx,cy,tx,ty; que[0][0]=1,que[0][1]=1; num[1][1]=0,a[1][1]=1; while(h<t) { cx=que[h][0],cy=que[h][1]; for(int i=0;i<12;i++) { tx=cx+dx[i],ty=cy+dy[i]; if(tx>=1&&tx<=100&&ty>=1&&ty<=100&&a[tx][ty]==0) { que[t][0]=tx,que[t][1]=ty; t++; num[tx][ty]=num[cx][cy]+1; a[tx][ty]=1; if(tx==ha&&ty==la)ans1=num[tx][ty]; if(tx==hb&&ty==lb)ans2=num[tx][ty]; if(ans1&&ans2)return; } } h++; } } int main(){ cin>>ha>>la>>hb>>lb; bfs(); cout<<ans1<<endl<<ans2; return 0; }
1248:Dungeon Master
#include<iostream> #include<cstring> using namespace std; const int mxn=25; int n,x,y,z,sx,sy,sz,ex,ey,ez,ans[100]; int map[mxn][mxn][mxn],flag[mxn][mxn][mxn],que[mxn*mxn*mxn][3]; int dx[6]={1,-1,0,0,0,0}; int dy[6]={0,0,1,-1,0,0}; int dz[6]={0,0,0,0,1,-1}; void bfs() { int h=0,t=0,cx,cy,cz,tx,ty,tz; que[0][0]=sx,que[0][1]=sy,que[0][2]=sz; while(h<=t) { cx=que[h][0],cy=que[h][1],cz=que[h][2]; for(int i=0;i<6;i++) { tx=cx+dx[i],ty=cy+dy[i],tz=cz+dz[i]; if(tx==ex&&ty==ey&&tz==ez) { ans[n]=map[cx][cy][cz]+1; return; } if(flag[tx][ty][tz]) { map[tx][ty][tz]=map[cx][cy][cz]+1; ++t; que[t][0]=tx,que[t][1]=ty,que[t][2]=tz; flag[tx][ty][tz]=0; } } h++; } } int main(){ char ch; while(1) { cin>>z>>x>>y; if(!(x||y||z))break; n++; memset(map,0,sizeof(map)); memset(flag,0,sizeof(flag)); for(int k=1;k<=z;k++) for(int i=1;i<=x;i++) for(int j=1;j<=y;j++) { cin>>ch; if(ch=='.')flag[i][j][k]=1; if(ch=='S')sx=i,sy=j,sz=k; if(ch=='E')ex=i,ey=j,ez=k; } bfs(); } for(int i=1;i<=n;i++) if(ans[i])cout<<"Escaped in "<<ans[i]<<" minute(s).\n"; else cout<<"Trapped!\n"; return 0; }
1249:Lake Counting
#include<iostream> using namespace std; const int mxn=114; int n,m,map[mxn][mxn],que[mxn*mxn][2],ans; int dx[]={1,-1,0,0,1,1,-1,-1}; int dy[]={0,0,1,-1,1,-1,1,-1}; void bfs(int x,int y) { int h=0,t=0,cx,cy,tx,ty; que[0][0]=x,que[0][1]=y; map[x][y]=0; while(h<=t) { cx=que[h][0],cy=que[h][1]; for(int i=0;i<8;i++) { tx=cx+dx[i],ty=cy+dy[i]; if(map[tx][ty]) { que[++t][0]=tx,que[t][1]=ty; map[tx][ty]=0; } } ++h; } } void dfs(int x,int y) { map[x][y]=0; int tx,ty; for(int i=0;i<8;i++) { tx=x+dx[i],ty=y+dy[i]; if(map[tx][ty])dfs(tx,ty); } } int main(){ int n,m; char ch; cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>ch; if(ch=='W')map[i][j]=1; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(map[i][j]) { ans++; bfs(i,j);//也可dfs(i,j); } } cout<<ans; return 0; }
1250:The Castle
#include<bits/stdc++.h> using namespace std; int a[52][52],p[52][52],mx,ans,fj; int dx[4]={0,-1,0,1}; int dy[4]={-1,0,1,0}; void dfs(int x,int y); int main(){ std::ios::sync_with_stdio(false); int r,c; cin>>r>>c; for(int i=1;i<=r;i++) for(int j=1;j<=c;j++) cin>>a[i][j]; for(int i=1;i<=r;i++) for(int j=1;j<=c;j++) { if(p[i][j]==0) { fj++; ans=0; dfs(i,j); if(mx<ans)mx=ans; } } cout<<fj<<endl<<mx; return 0; } void dfs(int x,int y) { ans++; p[x][y]=1; int tx,ty; for(int i=0;i<4;i++) { if((a[x][y]>>i)%2==0) { tx=x+dx[i],ty=y+dy[i]; if(p[tx][ty]==0)dfs(tx,ty); } } }
1251:仙岛求药
#include<iostream> #include<cstring> using namespace std; int const mx=22; int a[mx][mx],m[mx*mx][mx*mx],que[mx*mx][mx*mx],ans[1000]; int ha,la,hb,lb,r,c,h,t; //m记录搜索路径 int dx[4]={1,0,-1,0}; int dy[4]={0,1,0,-1}; int bfs(int x,int y) ; int main(){ char ch; int tmp=0; while(1) { cin>>r>>c; if(r==0&&c==0)break; memset(a,0,sizeof(a)); memset(m,0,sizeof(m)); for(int i=1;i<=r;i++) for(int j=1;j<=c;j++) { cin>>ch; if(ch=='.')a[i][j]=1; if(ch=='@')ha=i,la=j; if(ch=='*')hb=i,lb=j; } m[ha][la]=0; ans[tmp++]=bfs(ha,la); } for(int i=0;i<tmp;i++)cout<<ans[i]<<endl; return 0; } int bfs(int x,int y) { que[0][0]=x,que[0][1]=y; int cx,tx,cy,ty; h=0,t=0; while(h<=t) { cx=que[h][0],cy=que[h++][1]; for(int i=0;i<=3;i++) { tx=cx+dx[i],ty=cy+dy[i]; if(tx==hb&&ty==lb) return m[cx][cy]+1; if(a[tx][ty]) { que[++t][0]=tx,que[t][1]=ty; a[tx][ty]=0; m[tx][ty]=m[cx][cy]+1; } } } return -1; }
1252:走迷宫
#include<iostream> using namespace std; int a[100][100],m[100][100],n,k,f,que[10000][10000],h,t; //m记录搜索路径 int dx[4]={1,0,-1,0}; int dy[4]={0,1,0,-1}; void bfs(int x,int y) ; int main(){ char ch; cin>>n>>k; for(int i=1;i<=n;i++) for(int j=1;j<=k;j++) { cin>>ch; if(ch=='.')a[i][j]=1; } m[1][1]=1; bfs(1,1); return 0; } void bfs(int x,int y) { que[0][0]=x,que[0][1]=y; int cx,tx,cy,ty; while(h<=t) { cx=que[h][0],cy=que[h++][1]; for(int i=0;i<=3;i++) { tx=cx+dx[i],ty=cy+dy[i]; if(tx==n&&ty==k) { cout<<m[cx][cy]+1; return; } if(a[tx][ty]) { que[++t][0]=tx,que[t][1]=ty; a[tx][ty]=0; m[tx][ty]=m[cx][cy]+1; } } } }
1253:抓住那头牛
#include<iostream> using namespace std; int m[10000000],n,k,f,que[10000000],h,t,p[10000000]; //m记录搜索路径 int zn(int x,int i); void bfs(int x) ; int main(){ cin>>n>>k; m[n]=0; bfs(n); return 0; } int zn(int x,int i) { if(i==1)return x-1; if(i==2)return x+1; return x*2; } void bfs(int x) { que[0]=x; int cx,tx; while(h<=t) { cx=que[h++]; for(int i=1;i<=3;i++) { tx=zn(cx,i); if(p[tx]==0&&tx<k+100000&&tx>=0) { if(tx==k) { cout<<m[cx]+1; return; } que[++t]=tx; p[tx]=1; m[tx]=m[cx]+1; } } } }
1254:走出迷宫
#include<bits/stdc++.h> using namespace std; int const mx=102; int dx[4]={0,1,0,-1}; int dy[4]={1,0,-1,0}; int a[mx][mx],que[mx*mx][2],ans,dp[mx][mx],ha,la,hb,lb; void bfs() { int h=0,t=0,cx,cy,tx,ty; que[0][0]=ha,que[0][1]=la; while(h<=t) { cx=que[h][0],cy=que[h++][1]; for(int i=0;i<4;i++) { tx=cx+dx[i]; ty=cy+dy[i]; if(tx==hb&&ty==lb) { ans=dp[cx][cy]+1; return ; } if(a[tx][ty]) { que[++t][0]=tx; que[t][1]=ty; dp[tx][ty]=dp[cx][cy]+1; a[tx][ty]=0; } } } } int main(){ int n,m; string ch; cin>>n>>m; for(int i=1;i<=n;i++) { cin>>ch; for(int j=1;j<=m;j++) { if(ch[j-1]=='.')a[i][j]=1; if(ch[j-1]=='S')ha=i,la=j; if(ch[j-1]=='T')hb=i,lb=j; } } dp[ha][la]=0; bfs(); cout<<ans; return 0; }
1255:迷宫问题
#include<iostream> using namespace std; int const mx=102; int dx[4]={0,1,0,-1}; int dy[4]={1,0,-1,0}; int a[mx][mx],que[mx*mx][2],ans,dp[mx][mx][2],ha=1,la=1,hb=5,lb=5; void pr(int x,int y) { if(x!=ha||y!=la)pr(dp[x][y][0],dp[x][y][1]); cout<<'('<<x-1<<','<<' '<<y-1<<')'<<endl; } void bfs() { int h=0,t=0,cx,cy,tx,ty; que[0][0]=ha,que[0][1]=la; while(h<=t) { cx=que[h][0],cy=que[h++][1]; for(int i=0;i<4;i++) { tx=cx+dx[i]; ty=cy+dy[i]; if(tx==hb&&ty==lb) { pr(cx,cy); cout<<'('<<hb-1<<','<<' '<<lb-1<<')'; return ; } if(a[tx][ty]) { que[++t][0]=tx; que[t][1]=ty; dp[tx][ty][0]=cx; dp[tx][ty][1]=cy; a[tx][ty]=0; } } } } int main(){ //std::ios::sync_with_stdio(false); int n=5,m=5; char ch; //cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>a[i][j]; if(a[i][j])a[i][j]=0; else a[i][j]=1; } bfs(); return 0; }
1256:献给阿尔吉侬的花束
#include<iostream> #include<cstring> using namespace std; int const mx=202; int dx[4]={0,1,0,-1}; int dy[4]={1,0,-1,0}; int map[mx][mx],que[mx*mx][2],dp[mx][mx],ans[mx],ha,la,hb,lb; int bfs() { int h=0,t=0,cx,cy,tx,ty; que[0][0]=ha,que[0][1]=la; while(h<=t) { cx=que[h][0],cy=que[h++][1]; for(int i=0;i<4;i++) { tx=cx+dx[i]; ty=cy+dy[i]; if(tx==hb&&ty==lb) { return dp[cx][cy]+1; } if(map[tx][ty]) { que[++t][0]=tx; que[t][1]=ty; dp[tx][ty]=dp[cx][cy]+1; map[tx][ty]=0; } } } return 0; } int main(){ //std::ios::sync_with_stdio(false); int t,n,m; char ch; cin>>t; for(int k=1;k<=t;k++) { cin>>n>>m; memset(map,0,sizeof(map)); memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>ch; if(ch=='.')map[i][j]=1; if(ch=='S')ha=i,la=j; if(ch=='E')hb=i,lb=j; } ans[k]= bfs(); } for(int k=1;k<=t;k++) { if(ans[k])cout<<ans[k]<<endl; else cout<<"oop!"<<endl; } return 0; }
1257:Knight Moves
#include<iostream> #include<cstring> using namespace std; int const mx=304; int dx[8]={2,2,1,1,-1,-1,-2,-2}; int dy[8]={-1,1,-2,2,-2,2,-1,1}; int map[mx][mx],que[mx*mx][2],dp[mx][mx],ans[mx],ha,la,hb,lb; int bfs() { int h=0,t=0,cx,cy,tx,ty; que[0][0]=ha,que[0][1]=la; while(h<=t) { cx=que[h][0],cy=que[h++][1]; for(int i=0;i<8;i++) { tx=cx+dx[i]; ty=cy+dy[i]; if(tx==hb&&ty==lb) { return dp[cx][cy]+1; } if(map[tx][ty]) { que[++t][0]=tx; que[t][1]=ty; dp[tx][ty]=dp[cx][cy]+1; map[tx][ty]=0; } } } return 0; } int main(){ //std::ios::sync_with_stdio(false); int t,n; char ch; cin>>t; for(int k=1;k<=t;k++) { cin>>n>>ha>>la>>hb>>lb; ha+=2,la+=2,hb+=2,lb+=2; memset(map,0,sizeof(map)); memset(dp,0,sizeof(dp)); for(int i=2;i<=n+1;i++) for(int j=2;j<=n+1;j++) map[i][j]=1; if(ha==hb&&la==lb) ans[k]=0; else ans[k]=bfs(); } for(int k=1;k<=t;k++)cout<<ans[k]<<endl; return 0; }
第九章 动态规划
第一节 动态规划的基本模型
1258:【例9.2】数字金字塔
#include <bits/stdc++.h> using namespace std; int a[1010][1010],f[1010][1010]; int main() { memset(a,0,sizeof(a)); memset(f,0,sizeof(f)); int R; cin>>R; for(int i=1;i<=R;i++) for(int j=1;j<=i;j++) { cin>>a[i][j]; } for(int i=1;i<=R;i++) { for(int i=R;i>=1;i--) for(int j=1;j<=i;j++) { f[i][j]=a[i][j]+max(f[i+1][j],f[i+1][j+1]); } } cout<<f[1][1]; return 0; }
1259:【例9.3】求最长不下降序列
//求最长不降子序列长度,一本通网站1259题 #include<iostream> using namespace std; int a[201],b[201],c[201],mx=1,mxn; void pr(int x) { if(b[x]>1)pr(c[x]); cout<<a[x]<<' '; return; } int main(){ int n; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; b[i]=1; } mxn=n;//如果最长不降子序列只有一个元素就输出最后一个元素 for(int i=2;i<=n;i++) for(int j=i-1;j>=1;j--) if(a[i]>=a[j]&&b[j]>=b[i]) { b[i]=b[j]+1; if(mx<=b[i])mx=b[i],mxn=i; c[i]=j; } cout<<"max="<<mx<<endl; if(mx>1)pr(c[mxn]);//本可以直接pr(mxn),但最后会多一个空格 cout<<a[mxn];//为避免最后多一个空格,最后一个元素单独输出 return 0; }
1260:【例9.4】拦截导弹(Noip1999)
#include<iostream> using namespace std; int a[1005],b[1005],c[1005],sum=1,maxx,n; int main() { while(cin>>a[n]) { b[n]=1; n++; } c[1]=a[1]; for(int i=0;i<n;i++) { for(int j=0;j<i;j++) { if(a[j]>=a[i]&&b[j]+1>=b[i]) b[i]=b[j]+1; } maxx=max(maxx,b[i]); } cout<<maxx<<endl; // for(int i=1;i<=n;i++) for(int i=0;i<n;i++) { int minn=35000,flag=0,x; for(int j=1;j<=sum;j++) { if(a[i]<=c[j]&&minn>c[j]) { minn=c[j]; flag=1; x=j; } } if(flag==0)c[++sum]=a[i]; else c[x]=a[i]; } cout<<sum; return 0; }
1261:【例9.5】城市交通路网
//1261:【例9.5】城市交通路网 #include<iostream> using namespace std; int a[10001][10001],b[10001][2],p[10001][10001]; int n; void bfs() { for(int cx=1;cx<n;cx++) { for(int i=1;i<=p[cx][0];i++) { int tmp=p[cx][i]; if(!b[tmp][0]||b[tmp][0]>b[cx][0]+a[cx][tmp]) { b[tmp][0]=b[cx][0]+a[cx][tmp]; b[tmp][1]=cx; } } } } void pr(int x) { if(x==1){cout<<"1";return;} pr(b[x][1]); cout<<' '<<x; } int main(){ cin>>n; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { cin>>a[i][j]; if(a[i][j]) { p[i][0]++; p[i][p[i][0]]=j; } } bfs(); cout<<"minlong="<<b[n][0]<<endl; pr(n); return 0; }
1262:【例9.6】挖地雷
//1262:【例9.6】挖地雷 #include<iostream> using namespace std; int dj[201],sl[201][2],gx[201][201],ans[2],p[201][2]; //sl[x][0]记录挖到x地窖能挖到雷数,sl[x][1]记录x地窖的前驱 void dfs(int x) { int tx; for(int i=1;i<=gx[x][0];i++) { tx=gx[x][i]; if(sl[tx][0]<sl[x][0]+dj[tx]) { sl[tx][0]=sl[x][0]+dj[tx]; sl[tx][1]=x; dfs(tx); } } } void pr(int x) { if(!sl[x][1])cout<<x; else { pr(sl[x][1]); cout<<'-'<<x; } return; } int main(){ int n,x,y; cin>>n; for(int i=1;i<=n;i++){ cin>>dj[i]; sl[i][0]=dj[i]; } for(int i=1;;i++) { cin>>x>>y; if(x==0&&y==0)break; p[y][0]=1; p[x][1]=1; gx[x][0]++; gx[x][gx[x][0]]=y; } for(int i=1;i<=n;i++) { if(!p[i][0])dfs(i); } for(int i=1;i<=n;i++) if(!p[i][1]&&sl[i][0]>ans[0])ans[0]=sl[i][0],ans[1]=i; pr(ans[1]); cout<<endl<<ans[0]; return 0; }
1263:【例9.7】友好城市
#include<bits/stdc++.h> using namespace std; struct yhcs { int csy; int cse; }a[10005]; int b[10005],c[10005]; int main() { int n,maxx,k,ans=0; cin>>n; for(int i=1;i<=n;i++) cin>>a[i].csy>>a[i].cse; for(int i=1;i<=n-1;i++) for(int j=1;j<=n-i;j++) if(a[j].csy>a[j+1].csy) swap(a[j],a[j+1]); for(int i=1;i<=10005;i++) b[i]=1; for(int i=1;i<=n;i++) { maxx=0; k=0; for(int j=1;j<=i-1;j++) { if(a[i].cse>a[j].cse&&b[j]>maxx) { maxx=b[j]; b[i]=b[j]+1; k=j; c[i]=k; } } } for(int i=1;i<=n;i++) { if(ans<b[i]) { ans=b[i]; } } cout<<ans; return 0; }
1264:【例9.8】合唱队形
//1264:【例9.8】合唱队形 #include<iostream> using namespace std; int n,sh,maxn,maxx,a[101],b[101][3],c[101][3]; int main(){ cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; maxn=1,maxx=1; b[1][0]=1,b[1][1]=1,b[1][2]=1; for(int i=2;i<=n;i++) { b[i][0]=1; for(int j=1;j<i;j++) { if(a[i]>a[j]&&b[i][0]<b[j][0]+1) { b[i][0]=b[j][0]+1; if(b[i][0]>maxn) maxn=b[i][0],maxx=i; } } b[i][1]=maxn,b[i][2]=maxx; } maxn=1,maxx=1; c[n][0]=1,c[n][1]=1,c[n][2]=1; for(int i=n-1;i>=1;i--) { c[i][0]=1; for(int j=n;j>i;j--) { if(a[i]>a[j]&&c[i][0]<c[j][0]+1) { c[i][0]=c[j][0]+1; if(c[i][0]>maxn) maxn=c[i][0],maxx=i; } } c[i][1]=maxn,c[i][2]=maxx; } maxn=0; for(int i=2;i<n;i++) { sh=b[i][1]+c[i][1]; if(b[i][2]==c[i][2])sh--; if(maxn<sh)maxn=sh; } cout<<n-maxn; return 0; }
1265:【例9.9】最长公共子序列
//1265:【例9.9】最长公共子序列 #include<iostream> using namespace std; string sa,sb; int f[1001][1001],pa,pb; int main(){ cin>>sa>>sb; int la=sa.size(),lb=sb.size(); for(int i=1;i<=la;i++) for(int j=1;j<=lb;j++) { f[i][j]=max(f[i-1][j],f[i][j-1]); if(sa[i-1]==sb[j-1])f[i][j]=max(f[i][j],f[i-1][j-1]+1); } cout<<f[la][lb]; return 0; }
1266:【例9.10】机器分配
//1266:【例9.10】机器分配 #include<iostream> using namespace std; int n,m,a[20][20],f[20][20],sl[20][20],maxn,maxx; void pr(int nn,int nm) { if(!nn)return; pr(nn-1,nm-sl[nn][nm]); cout<<nn<<' '<<sl[nn][nm]<<endl; } int main(){ cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)cin>>a[i][j]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { maxn=0; //擂台第i个公司得到机器数量 k //求出最大值存于f[i][j]中 //第i个公司实得机器数量存在sl[i][j]中 for(int k=0;k<=j;k++) if(maxn<f[i-1][k]+a[i][j-k]) maxn=f[i-1][k]+a[i][j-k],maxx=j-k; f[i][j]=maxn,sl[i][j]=maxx; } cout<<f[n][m]<<endl; pr(n,m); return 0; }
1281:最长上升子序列
//1281:最长上升子序列 #include<iostream> using namespace std; int n,a[1001],b[1001],ans; int main(){ cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; b[1]=1; for(int i=2;i<=n;i++) { b[i]=1; for(int j=1;j<i;j++) if(a[i]>a[j]&&b[i]<b[j]+1) { b[i]=b[j]+1; if(ans<b[i])ans=b[i]; } } cout<<ans; return 0; }
1282:最大子矩阵
#include <iostream> #include <cstring> using namespace std; const int maxn =101;//n,m行列值最大100 int n,m,res=-127; //res取到最小整数就好 int a[maxn][maxn],b[maxn],dp[maxn]; int main() { cin>>n; m=n; for(int i=0;i<n;i++) for(int j=0;j<m;j++) cin>>a[i][j]; for(int x=0;x<n;x++){//设置起始行 memset(b,0,sizeof(b));//设置结束行 for(int y=x;y<n;y++) { for(int j=0;j<m;j++) b[j]+=a[y][j];//b存储第起始行x到y行到中每一列的值 dp[0]=b[0]; if(dp[0]>res)//不要忘了这个 res=dp[0]; for(int i=1;i<m;i++) { if(dp[i-1]<0) dp[i]=b[i]; else dp[i]=dp[i-1]+b[i]; if(dp[i]>res) //维护最后的结果 res=dp[i]; } } } cout<<res<<endl; return 0; }
1283:登山
//1283:登山 #include<iostream> using namespace std; int n,sh,maxn,maxx,a[1001],b[1001][3],c[1001][3]; int main(){ cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; maxn=1,maxx=1; b[1][0]=1,b[1][1]=1,b[1][2]=1; for(int i=2;i<=n;i++) { b[i][0]=1; for(int j=1;j<i;j++) { if(a[i]>a[j]&&b[i][0]<b[j][0]+1) { b[i][0]=b[j][0]+1; if(b[i][0]>maxn) maxn=b[i][0],maxx=i; } } b[i][1]=maxn,b[i][2]=maxx; } maxn=1,maxx=1; c[n][0]=1,c[n][1]=1,c[n][2]=1; for(int i=n-1;i>=1;i--) { c[i][0]=1; for(int j=n;j>i;j--) { if(a[i]>a[j]&&c[i][0]<c[j][0]+1) { c[i][0]=c[j][0]+1; if(c[i][0]>maxn) maxn=c[i][0],maxx=i; } } c[i][1]=maxn,c[i][2]=maxx; } maxn=0; for(int i=2;i<n;i++) { sh=b[i][1]+c[i][1]; if(b[i][2]==c[i][2]||b[i][2]!=c[i][2]&&a[b[i][2]]==a[c[i][2]])sh--; if(maxn<sh)maxn=sh; } cout<<maxn; return 0; }
1284:摘花生
//1284:摘花生 #include<iostream> using namespace std; int t,n,m,map[101][101],f[101][101]; int main(){ cin>>t; for(int k=1;k<=t;k++) { cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)cin>>map[i][j]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) f[i][j]=max(f[i-1][j],f[i][j-1])+map[i][j]; cout<<f[n][m]<<endl; } return 0; }
1285:最大上升子序列和
//1285:最大上升子序列和 #include<iostream> using namespace std; int n,a[1001],b[1001],ans; int main(){ cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; b[1]=a[1]; for(int i=2;i<=n;i++) { b[i]=a[i]; for(int j=1;j<i;j++) if(a[i]>a[j]&&b[i]<b[j]+a[i]) { b[i]=b[j]+a[i]; if(ans<b[i])ans=b[i]; } } cout<<ans; return 0; }
1286:怪盗基德的滑翔翼
//1286:怪盗基德的滑翔翼 #include<iostream> using namespace std; int k,n,a[1001],b[1001],ans; int main(){ cin>>k; for(int i=1;i<=k;i++) { cin>>n; for(int j=1;j<=n;j++)cin>>a[j]; b[1]=1; ans=1; for(int j=2;j<=n;j++) { b[j]=1; for(int m=1;m<j;m++) if(a[j]<a[m]&&b[j]<b[m]+1) { b[j]=b[m]+1; if(ans<b[j])ans=b[j]; } } for(int j=2;j<=n;j++) { b[j]=1; for(int m=1;m<j;m++) if(a[j]>a[m]&&b[j]<b[m]+1) { b[j]=b[m]+1; if(ans<b[j])ans=b[j]; } } cout<<ans<<endl; } return 0; }
1287:最低通行费
//1287:最低通行费 #include<iostream> #include<cmath> using namespace std; int n,a[101][100],f[101][101]; int main(){ cin>>n; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)cin>>a[i][j]; for(int i=0;i<=n;i++)f[i][0]=f[0][i]=10000; f[1][0]=0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { f[i][j]=min(f[i][j-1],f[i-1][j])+a[i][j]; } cout<<f[n][n]; return 0; }
1288:三角形最佳路径问题
//1288:三角形最佳路径问题 #include<iostream> using namespace std; int n,a[101][101],f[101][101],ans; int main(){ cin>>n; for(int i=1;i<=n;i++) for(int j=1;j<=i;j++)cin>>a[i][j]; for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) f[i][j]=max(f[i-1][j],f[i-1][j-1])+a[i][j]; for(int i=1;i<=n;i++) if(ans<f[n][i])ans=f[n][i]; cout<<ans; return 0; }
1289:拦截导弹
//1289:拦截导弹 #include<iostream> using namespace std; int n,a[20],f[20],ans; int main(){ cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; f[1]=1; for(int i=2;i<=n;i++) { f[i]=1; for(int j=1;j<i;j++) if(a[i]<=a[j]&&f[i]<f[j]+1) { f[i]=f[j]+1; if(ans<f[i])ans=f[i]; } } cout<<ans; return 0; }
第二节 背包问题
1267:【例9.11】01背包问题
#include<iostream> using namespace std; int w[31],c[31],m,n,mx,tc; void dfs(int t0,int dp) { if(t0+w[dp]<=m) { tc+=c[dp]; if(mx<tc)mx=tc; if(dp>1)dfs(t0+w[dp],dp-1); tc-=c[dp]; } if(dp>1)dfs(t0,dp-1); return; } int main(){ cin>>m>>n; for(int i=1;i<=n;i++) cin>>w[i]>>c[i]; dfs(0,n); cout<<mx; return 0; }
1268:【例9.12】完全背包问题
#include<cstdio> #include<string.h> #include<iostream> using namespace std; int M,n,w[10000],c[10000],f[10000][10000]; int main() { cin>>M>>n; for(int i=1;i<=n;i++) cin>>w[i]>>c[i]; for(int i=1;i<=n;i++) for(int j=1;j<=M;j++) { if(w[i]>j)f[i][j]=f[i-1][j]; else f[i][j]=max(f[i][j-w[i]]+c[i],f[i-1][j]); } cout<<"max="<<f[n][M]; return 0; }
1269:【例9.13】庆功会
#include<iostream> using namespace std; int a[501],b[501],c[501],f[6001]; int mx(int a,int b) { if(a>=b)return a; else return b; } int main() { int n,m; cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]>>b[i]>>c[i]; for(int i=1;i<=n;i++) for(int j=1;j<=c[i];j++) for(int k=m;k>=0;k--) if(a[i]<=k)f[k]=mx(f[k],f[k-a[i]]+b[i]); cout<<f[m]; return 0; }
1270:【例9.14】混合背包
#include<iostream> #include<cstdio> using namespace std; int main() { //freopen("a.txt","r",stdin); int v,n; while(scanf("%d%d",&v,&n)!=EOF) { int w[1000],c[1000],p[1000],i,k=0,t,j,f[202]={0}; for(i=1;i<=n;i++) { t=1; scanf("%d%d%d",&w[i],&c[i],&p[i]); if(p[i]>1) //将有限个相同价格的物品转化为不同价格的单个物品 { while(p[i]>t) { k++; w[n+k]=w[i]*t; c[n+k]=c[i]*t; p[n+k]=1; p[i]-=t; t*=2; } w[i]*=p[i]; c[i]*=p[i]; p[i]=1; } } for(i=1;i<=n+k;i++) if(p[i]==1) //判断是01背包还是完全背包 for(j=v;j>=w[i];j--) f[j]=f[j]>f[j-w[i]]+c[i] ? f[j]:f[j-w[i]]+c[i]; else for(j=w[i];j<=v;j++) f[j]=f[j]>f[j-w[i]]+c[i] ? f[j]:f[j-w[i]]+c[i]; printf("%d\n",f[v]); } return 0; }
1271:【例9.15】潜水员
#include<iostream> #include<cstring> using namespace std; int f[101][101],a[5000],b[5000],c[5000]; int main() { int O,N,n; memset(f,127,sizeof(f)); cin>>O>>N>>n; for(int i=1;i<=n;i++) cin>>a[i]>>b[i]>>c[i]; f[0][0]=0; for(int i=1;i<=n;i++) { for(int j=O;j>=0;j--) { for(int t=N;t>=0;t--) { int O1=j+a[i]; if(O1>=O)O1=O; int N1=t+b[i]; if(N1>=N)N1=N; if(f[O1][N1]>f[j][t]+c[i])f[O1][N1]=f[j][t]+c[i]; } } } cout<<f[O][N]; return 0; }
1272:【例9.16】分组背包
#include<bits/stdc++.h> using namespace std; int dp[205]; int v, n, t; int we[35], c[35]; vector<int>ve[35]; int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); int p; cin >> v >> n >> t; for(int i = 1; i <= n; i++) { scanf("%d%d%d", &we[i], &c[i], &p); ve[p].push_back(i); } for(int i = 1; i <= t; i++) { for(int j = v; j >= 0; j--) { for(int k = 0; k < ve[i].size(); k++) { int x = ve[i][k]; if (j >= we[x]) dp[j] = max(dp[j], dp[j-we[x]]+c[x]); } } } printf("%d\n", dp[v]); return 0; }
1273:【例9.17】货币系统
#include<iostream> using namespace std; int n,m,a[101]; long long f[10001]; int main(){ cin>>n>>m; for(int i=1;i<=n;i++)cin>>a[i]; f[0]=1; for(int i=1;i<=n;i++) for(int j=0;j<=m-a[i];j++) f[j+a[i]]+=f[j]; cout<<f[m]; return 0; }
1290:采药
//1290:采药 #include<iostream> using namespace std; int tt,n,w[101],v[101],f[10001]; int main(){ cin>>tt>>n; for(int i=1;i<=n;i++)cin>>w[i]>>v[i]; for(int i=1;i<=n;i++) for(int j=tt;j>0;j--) if(j>=w[i]) f[j]=max(f[j],f[j-w[i]]+v[i]); cout<<f[tt]; return 0; }
1291:数字组合
//1291:数字组合 #include<iostream> using namespace std; int n,m,a[21]; long long f[20001]; int main(){ cin>>n>>m; for(int i=1;i<=n;i++)cin>>a[i]; f[0]=1; for(int i=1;i<=n;i++) for(int j=m;j>=a[i];j--) f[j]+=f[j-a[i]]; cout<<f[m]; return 0; }
1292:宠物小精灵之收服
//1292:宠物小精灵之收服 #include<iostream> using namespace std; int f[1010][1010],n,m,k,i,j,l,a,b; int main() { cin>>n>>m>>k; for(int l=1;l<=k;l++) { cin>>a>>b; for(int i=n;i>=a;i--) for(int j=m;j>=b;j--) if(f[i][j]<f[i-a][j-b]+1) f[i][j]=f[i-a][j-b]+1; } cout<<f[n][m]<<' '; i=m; while(i>=0&&f[n][i]==f[n][m])i--; cout<<m-i-1; }
1293:买书
//1293:买书 #include<iostream> using namespace std; int n=4,m,a[4]={10,20,50,100}; long long f[10001]; int main(){ cin>>m; f[0]=1; for(int i=0;i<n;i++) for(int j=a[i];j<=m;j++) f[j]+=f[j-a[i]]; cout<<f[m]; return 0; }
1294:Charm Bracelet
//1294:Charm Bracelet #include<iostream> using namespace std; int n,m,w[3501],v[3501],f[12881]; int main(){ cin>>n>>m; for(int i=1;i<=n;i++)cin>>w[i]>>v[i]; for(int i=1;i<=n;i++) for(int j=m;j>=w[i];j--) if(f[j]<f[j-w[i]]+v[i])f[j]=f[j-w[i]]+v[i]; cout<<f[m]; return 0; }
1295:装箱问题
//1295:装箱问题 #include<iostream> using namespace std; int n,m,w[31],f[20001]; int main(){ cin>>m>>n; for(int i=1;i<=n;i++)cin>>w[i]; for(int i=1;i<=n;i++) for(int j=m;j>=w[i];j--) if(f[j]<f[j-w[i]]+w[i])f[j]=f[j-w[i]]+w[i]; cout<<m-f[m]; return 0; }
1296:开餐馆
//1296:开餐馆 #include<iostream> #include<cmath> #include<cstring> using namespace std; int a[100],b[101],f[101],ans; int t,n,k,m; int main(){ cin>>t; for(int l=1;l<=t;l++) { memset(a,0,sizeof(a)); memset(f,0,sizeof(f)); ans=0; cin>>n>>k; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=n;i++)cin>>b[i]; for(int i=1;i<=n;i++) { f[i]=b[i]; for(int j=1;j<i;j++) if(a[i]-a[j]>k) f[i]=max(f[i],f[j]+b[i]); if(ans<f[i])ans=f[i]; } cout<<ans<<endl; } return 0; }
第三节 动态规划经典题
1274:【例9.18】合并石子
#include<iostream> #include<cstring> using namespace std; int a[101],f[101][101],s[101]; int main() { int n; cin>>n; memset(f,1,sizeof(f)); for(int i=1;i<=n;i++) { cin>>a[i]; f[i][i]=0; s[i]=s[i-1]+a[i]; } for(int i=n;i>0;i--) for(int j=i+1;j<=n;j++) for(int k=i;k<j;k++) if(f[i][j]>f[i][k]+f[k+1][j]+s[j]-s[i-1]) f[i][j]=f[i][k]+f[k+1][j]+s[j]-s[i-1]; cout<<f[1][n]<<endl; return 0; }
1275:【例9.19】乘积最大
//1275:【例9.19】乘积最大 #include<iostream> using namespace std; int n,k,a[11],b[11][11],f[11][11]; char ch; int main(){ cin>>n>>k; for(int i=1;i<=n;i++) { cin>>ch; a[i]=ch-'0'; } for(int i=1;i<=n;i++) { b[i][i]=a[i]; for(int j=i+1;j<=n;j++) b[i][j]=b[i][j-1]*10+a[j]; } for(int i=1;i<=n;i++)f[i][0]=b[1][i]; for(int j=1;j<=k;j++) for(int i=j+1;i<=n;i++) for(int l=j;l<i;l++) f[i][j]=max(f[i][j],f[l][j-1]*b[l+1][i]); cout<<f[n][k]; return 0; }
1276:【例9.20】编辑距离
//1276:【例9.20】编辑距离 #include<iostream> using namespace std; string s1,s2; int f[2001][2001]; int mmin(int x,int y,int z) { if(x>y)swap(x,y); if(x>z)swap(x,z); return x; } int main(){ cin>>s1>>s2; int l1=s1.size(),l2=s2.size(); for(int i=1;i<=l1;i++)f[i][0]=i; for(int i=1;i<=l2;i++)f[0][i]=i; for(int i=1;i<=l1;i++) for(int j=1;j<=l2;j++) { if(s1[i-1]==s2[j-1])f[i][j]=f[i-1][j-1]; else f[i][j]=mmin(f[i-1][j],f[i][j-1],f[i-1][j-1])+1; } cout<<f[l1][l2]; return 0; }
1277:【例9.21】方格取数
//1277:【例9.21】方格取数 #include<iostream> using namespace std; int n,a[11][11],b[11][11][11][11]; int main(){ cin>>n; int x,y,z; while(cin>>x>>y>>z) { if(x==0&&y==0&&z==0)break; a[x][y]=z; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) for(int k=1;k<=n;k++) for(int l=1;l<=n;l++) { int tmp1=max(b[i-1][j][k][l-1],b[i-1][j][k-1][l]); int tmp2=max(b[i][j-1][k][l-1],b[i][j-1][k-1][l]); b[i][j][k][l]=max(tmp1,tmp2)+a[i][j]; if(i!=k&&j!=l)b[i][j][k][l]+=a[k][l]; } cout<<b[n][n][n][n]; return 0; }
1278:【例9.22】复制书稿(book)
//1278:【例9.22】复制书稿(book) #include<iostream> using namespace std; int m,k,a[501],f[501][501],sum[501]; int maxx(int x,int y) { return x>y?x:y; } int minn(int x,int y) { return x<y?x:y; } void pr(int x,int y) { if(x<1)return; if(y==1) { cout<<1<<' '<<x<<endl; return; } int pd=x,pdz=a[x]; while(pdz<=f[m][k]&&pd>=1)//从最后一个人最后一本书开始,只要不超量就让他写 { pdz+=a[pd-1]; pd--; } pr(pd,y-1); cout<<pd+1<<' '<<x<<endl; return; } int main(){ cin>>m>>k; for(int i=1;i<=m;i++) for(int j=1;j<=k;j++) f[i][j]=1e6; for(int i=1;i<=m;i++) { cin>>a[i]; sum[i]=sum[i-1]+a[i]; f[i][1]=sum[i]; } for(int j=2;j<=k;j++) for(int i=j;i<=m;i++) for(int l=j-1;l<i;l++) { int tmp=maxx(f[l][j-1],sum[i]-sum[l]); f[i][j]=minn(f[i][j],tmp); } pr(m,k); return 0; }
1279:【例9.23】橱窗布置(flower)
//1279:【例9.23】橱窗布置(flower) #include<iostream> using namespace std; int f,v,a[101][101],c[101][101],d[101][101]; int mmax(int x,int y){return x>y?x:y;} void pr(int x,int y) { if(x==1)cout<<d[1][y]; else { pr(x-1,d[x][y]-1); cout<<' '<<d[x][y]; } return; } int main(){ cin>>f>>v; for(int i=1;i<=f;i++) for(int j=1;j<=v;j++)cin>>a[i][j],c[i][j]=-1e7; for(int i=0;i<=v;i++)c[0][i]=0; for(int i=1;i<=f;i++) for(int j=i;j<=v;j++) for(int k=i;k<=j;k++) { if(c[i][j]<c[i-1][k-1]+a[i][k]) c[i][j]=c[i-1][k-1]+a[i][k],d[i][j]=k; } cout<<c[f][v]<<endl; pr(f,v); return 0; }
1280:【例9.24】滑雪
//1280:【例9.24】滑雪 #include<iostream> using namespace std; int r,c,a[101][101],f[101][101],ans; int dx[]={1,0,-1,0}; int dy[]={0,1,0,-1}; int dfs(int x,int y) { if(f[x][y])return f[x][y]; f[x][y]=1; for(int i=0;i<4;i++) { int tx=x+dx[i],ty=y+dy[i]; if(tx>=1&&tx<=r&&ty>=1&&ty<=c&&a[x][y]>a[tx][ty]) { int tmp=dfs(tx,ty)+1; if(f[x][y]<tmp)f[x][y]=tmp; } } return f[x][y]; } int main(){ cin>>r>>c; for(int i=1;i<=r;i++) for(int j=1;j<=c;j++)cin>>a[i][j]; for(int i=1;i<=r;i++) for(int j=1;j<=c;j++) dfs(i,j); for(int i=1;i<=r;i++) for(int j=1;j<=c;j++) if(ans<f[i][j])ans=f[i][j]; cout<<ans; return 0; }
1297:公共子序列
//1297:公共子序列 #include<iostream> #include<cstdio> #include<cstring> using namespace std; int f[1001][1001]; int ggxl(string sa,string sb) { int la=sa.size(),lb=sb.size(); for(int i=1;i<=la;i++) for(int j=1;j<=lb;j++) { f[i][j]=max(f[i-1][j],f[i][j-1]); if(sa[i-1]==sb[j-1])f[i][j]=max(f[i][j],f[i-1][j-1]+1); } return f[la][lb]; } int main(){ string s1,s2; while(cin>>s1>>s2) { memset(f,0,sizeof(f)); cout<<ggxl(s1,s2)<<endl; } return 0; }
1298:计算字符串距离
//1298:计算字符串距离 #include<iostream> #include<cstring> using namespace std; string s1,s2; int f[1001][1001]; int mmin(int a,int b,int c) { if(a>b)swap(a,b); if(a>c)swap(a,c); return a; } int edstr(string x,string y) { int l1=x.size(),l2=y.size(); for(int i=1;i<=l1;i++)f[i][0]=i; for(int i=1;i<=l2;i++)f[0][i]=i; for(int i=1;i<=l1;i++) for(int j=1;j<=l2;j++) { if(x[i-1]==y[j-1])f[i][j]=f[i-1][j-1]; else f[i][j]=mmin(f[i-1][j],f[i][j-1],f[i-1][j-1])+1; } return f[l1][l2]; } int main(){ int n; cin>>n; for(int i=1;i<=n;i++) { cin>>s1>>s2; cout<<edstr(s1,s2)<<endl; } return 0; }
1299:糖果
//1299:糖果 #include<iostream> using namespace std; int n,m,x,f[101][101]; int main(){ cin>>n>>m; for(int i=1;i<=n;i++) { cin>>x; f[i][x%m]=x; for(int j=0;j<m;j++) if(f[i-1][j])f[i][(j+x)%m]=f[i-1][j]+x; for(int j=0;j<m;j++) if(f[i][j]<f[i-1][j])f[i][j]=f[i-1][j]; } cout<<f[n][0]; return 0; }
1300:鸡蛋的硬度
//1300:鸡蛋的硬度 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int f[110][11]; int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { memset(f,0,sizeof(f)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) f[i][j]=i; for(int j=1;j<=n;j++) for(int i=2;i<=m;i++) for(int k=1;k<=j;k++)//枚举 f[j][i]=min(f[j][i],max(f[k-1][i-1],f[j-k][i])+1); /*在1~j层楼间选择第k层扔下鸡蛋,如果破了,说明硬度介于1~k-1之间 , 问题变成用i-1个鸡蛋去测k-1层楼的硬度。如果没破则说明硬度介于k~j之间, 问题变成用i个鸡蛋去测j-k层楼的硬度,题目要求是最坏的情况下,故要取两者最大值 */ printf("%d\n",f[n][m]); } return 0; }
1301:大盗阿福
//1301:大盗阿福 #include<iostream> using namespace std; int t,n,a[100001],f[100001],ans; int maxx(int x,int y){return x>y?x:y;} int main(){ cin>>t; for(int l=1;l<=t;l++) { cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; f[1]=a[1]; for(int i=2;i<=n;i++) f[i]=maxx(f[i-1],f[i-2]+a[i]); cout<<f[n]<<endl; } return 0; }
1302:股票买卖
#include<bits/stdc++.h> using namespace std; const int MAX_NUM = 100005; int price[MAX_NUM]; int pre[MAX_NUM]; int post[MAX_NUM]; int max_profit; int main() { int num; scanf("%d",&num); while (num--) { int days; //memset(price, 0, sizeof(price)); memset(pre, 0, sizeof(pre)); memset(post, 0, sizeof(post)); scanf("%d",&days); for (int i = 0; i < days; i++) { scanf("%d",&price[i]); } //前i天中价格最小的一天买,第i天卖获取的最大利润 //初始化,计算pre pre[0] = 0; int min_price = price[0]; for (int i = 1; i<days; i++) { pre[i] = max(pre[i - 1], price[i] - min_price); if (min_price>price[i]) min_price = price[i]; } //第j天买,之后寻找卖的一天,获取最大利润 //初始化,并且计算post post[days - 1] = 0;//初始化为0 int max_price = price[days-1]; for (int j = days - 2; j >= 0; j--) { post[j] = max(post[j + 1], max_price - price[j]); if (max_price < price[j]) max_price = price[j]; } //进行遍历,输出最大值 max_profit = pre[0] + post[0]; for (int k = 0; k < days; k++) { max_profit = max(pre[k] + post[k],max_profit); } cout << max_profit << endl; } return 0; }
1303:鸣人的影分身
#include<iostream> using namespace std; int main() { int t,m,n,i,j,a[100][100]; for(i=0;i<11;i++) { a[0][i]=1; a[i][0]=0; } for(i=1;i<11;i++) for(j=1;j<11;j++) if(j-1>=0&&i-j>=0)a[i][j]=a[i][j-1]+a[i-j][j]; else if(j-1<0&&i-j>=0)a[i][j]=a[i-j][j]; else if(j-1>=0&&i-j<0)a[i][j]=a[i][j-1]; cin>>t; while(t--) { cin>>m>>n; cout<<a[m][n]<<endl; } }
1304:数的划分
#include<iostream> using namespace std; int ans,a[100]={1},n,k; void dfs(int n,int dp) { if(dp==k) { ans++; return; } for(int i=a[dp-1];i*(k+1-dp)<=n;i++) { a[dp]=i; dfs(n-i,dp+1); } } int main(){ cin>>n>>k; dfs(n,1); cout<<ans; return 0; }
1305:Maximum sum
//1305:Maximum sum #include<iostream> using namespace std; int t,n,a[50005],lsum[50005],rsum[50005],lmx[50005],rmx[50005],lmax,rmax,maxx; int main(){ cin>>t; for(int l=1;l<=t;l++) { cin>>n; lmax=rmax=maxx=-1e6; rsum[n+1]=0; for(int i=1;i<=n;i++) { cin>>a[i]; if(lsum[i-1]>=0)lsum[i]=lsum[i-1]+a[i]; else lsum[i]=a[i]; if(lmax<lsum[i])lmax=lsum[i]; lmx[i]=lmax; } for(int i=n;i>0;i--) { if(rsum[i+1]>=0)rsum[i]=rsum[i+1]+a[i]; else rsum[i]=a[i]; if(rmax<rsum[i])rmax=rsum[i]; rmx[i]=rmax; } for(int i=1;i<n;i++) if(maxx<lmx[i]+rmx[i+1])maxx=lmx[i]+rmx[i+1]; cout<<maxx<<endl; } return 0; }
1306:最长公共子上升序列
#include <cstdio> #include <iostream> #include <vector> #define INF 1e9 using namespace std; struct nod { int val; vector<int>v; }f[505]; int a[505],b[505]; int main() { int n,m,i,j; scanf("%d",&m); for (i=1;i<=m;i++) scanf("%d",&a[i]); scanf("%d",&n); for (i=1;i<=n;i++) scanf("%d",&b[i]); for (i=1;i<=n;i++) { nod k; k.val=0; for (j=1;j<=m;j++) { if (b[i]>a[j] && k.val<f[j].val) k=f[j]; if (b[i]==a[j]) { f[j].val=k.val+1; f[j].v=k.v; f[j].v.push_back(b[i]); } } } nod Max = f[1]; for (int i=2;i<=m;i++) if (f[i].val>Max.val) Max = f[i]; printf("%d\n",Max.val); for (int i =0; i < Max.v.size(); i++) printf("%d ",Max.v[i]); printf("\n"); }
第三部分 数据结构
第一章 栈
1331:【例1-2】后缀表达式的值
#include<iostream> #include<cstdio> #include<cstring> using namespace std; long long a[1001],top,tp; char b[1001]; int main() { int flag=1;//值为1表示正常情况,-1表示正在输入一个负数,0则表示刚输入一个“-”,是负号还是减号待定 long long ts=0; char ch; while(ch=getchar()) { if(ch>='0'&&ch<='9') { if(flag==0)flag=-1; ts=ts*10+ch-'0'; } else { if(flag==0) { b[++tp]='-'; flag=1; } if(ch=='@')break; if(ch=='-')flag=0; else if(ch==' ') { ts*=flag; a[++top]=ts; flag=1; ts=0; } else b[++tp]=ch; } } for(int i=1;i<=tp;i++) { ch=b[i]; ts=a[top--]; switch(ch) { case '+':a[top]+=ts;break; case '-':a[top]-=ts;break; case '*':a[top]*=ts;break; default:a[top]/=ts; } } cout<<a[top]<<endl; return 0; }
1353:表达式括号匹配(stack)
#include<iostream> using namespace std; int top; int main(){ string s; getline(cin,s,'@'); int l=s.size() ; for(int i=0;i<l;i++) if(s[i]=='(')top++; else if(s[i]==')')if(top<1) { cout<<"NO"; return 0; } else top--; if(top)cout<<"NO"; else cout<<"YES"; return 0; }
1354:括弧匹配检验
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int top; char a[1000]; int main(){ char s[1000]; gets(s); int l=strlen(s); for(int i=0;i<l;i++) if(s[i]=='('||s[i]=='[')a[++top]=s[i]; else if(s[i]==')') if(top==0||a[top]!='(') { cout<<"Wrong"; return 0; } else top--; else if(s[i]==']') if(top==0||a[top]!='[') { cout<<"Wrong"; return 0; } else top--; if(top)cout<<"Wrong"; else cout<<"OK"; return 0; }
1355:字符串匹配问题(strs)
#include<cstdio> #include<iostream> #include<cstring> using namespace std; char a[]={'{','[','(','<','}',']',')','>'};//{→0 [→1 (→2 <→3 }→4 ]→5 )→6 >→7 char str[300]; int b[300],stack[300]; int main() { int n; int k; cin>>n;//输入测试数据组数 while(n--) { int top=0; bool flag=true;//用于判断嵌套是否合法的标记 cin>>str; int len=strlen(str); for(int i=0;i<len;i++) for(int j=0;j<8;j++) if(str[i]==a[j]) { b[i]=j;////建立映射 break;//跳出内循环 } for(int i=0;i<len;i++)//判断是否匹配 { if(b[i]<=3)//b[i]元素入栈 { if(top==0||b[i]>=stack[top])//b[i]元素可以入栈 { top++; stack[top]=b[i]; } else//元素无法入栈,说明该组数据非法 { flag=false; break; } } else if(b[i]>=4)//判断是否配对 { if(top>0&&stack[top]+4==b[i])//可以配对 top--; else//无法配对 { flag=false; break; } } } if(top) cout<<"NO"<<endl;//栈内有元素,匹配不成功 else if(flag==1) cout<<"YES"<<endl;//栈内无元素,匹配成功 else cout<<"NO"<<endl;//栈内无元素,匹配不成功 } return 0; }
1356:计算(calc)
//1356:计算(calc) /*基本思路:后面优先级高,前面内容入栈,否则先算前面内容*/ #include<iostream> #include<stack> #include<cmath> #include<cstring> using namespace std; int const N=1e5+1; int x,y; char ch,ch0; string s; stack<int>s1; stack<char>s2; //计算运算优先组,后面优先级高就前面内容入栈,后面优先级小于等于前面优先组就先算栈内内容 int level(char p) { if(p=='+'||p=='-')return 1; if(p=='*'||p=='/')return 2; if(p=='^')return 3; return 0; } //完成一次基本计算 void calc() { int m,n; char z; n=s1.top(); s1.pop(); m=s1.top(); s1.pop(); z=s2.top(); s2.pop(); switch(z) { case '+':s1.push(m+n);break; case '-':s1.push(m-n);break; case '*':s1.push(m*n);break; case '/':s1.push(m/n);break; default:s1.push(pow(m,n)); } return; } int main(){ cin>>s; s='('+s+')'; int i=0; ch='('; do { if(ch=='(') { s2.push('('); } //遇到)就计算到(为止。遇到(之前,栈内所存运算符应该逐级上升,故需反向运算 //如1+2*3^4 else if(ch==')') { while(s2.top()!='(')calc(); s2.pop();//弹出( } else if(ch>='0'&&ch<='9'||ch=='-'&&s[i-1]=='(') //读到的是数字,把连续的数字变成数值 ,如果是'-'先判断前面是不是(,是则说明是负号不是减号 { if(ch=='-')x=0,y=-1;//是负号则符号设为-1,初始值为0 else x=ch-'0',y=1;//默认符号为正 ch0=s[++i]; while(ch0>='0'&&ch0<='9')x=x*10+ch0-'0',ch0=s[++i]; i--; x*=y; s1.push(x); } else //ch为运算符 { while(level(ch)<=level(s2.top()))//当前运算符不超过栈顶运算,先算栈顶运算 { calc(); } s2.push(ch);//直到当前运算符高于栈顶运算符再把运算符存栈 } }while(ch=s[++i]); cout<<s1.top()<<endl; return 0; }
1357:车厢调度(train)
#include<bits/stdc++.h> using namespace std; int a[1001],b[1001]; int main(){ std::ios::sync_with_stdio(false); int n; cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; int j=0,k=1; for(int i=1;i<=n;i++) { while(k<a[i])b[++j]=k++; if(k==a[i])k++; else if(b[j]==a[i]&&j>0)j--; else { cout<<"NO"; return 0; } } cout<<"YES"; return 0; }
1358:中缀表达式值(expr)
//1358:中缀表达式值(expr) /*基本思路:后面优先级高,前面内容入栈,否则先算前面内容*/ #include<iostream> #include<stack> #include<cmath> #include<cstring> using namespace std; int const N=1e5+1; int x,y; char ch,ch0; string s; stack<int>s1; stack<char>s2; //计算运算优先组,后面优先级高就前面内容入栈,后面优先级小于等于前面优先组就先算栈内内容 bool chkh() { for(int i=0;i<s.size();i++) if(s[i]=='(')s2.push('('); else if(s[i]==')'||i==s.size()-1&&s[i]=='@') if(s2.empty())return false; else s2.pop(); if(s2.empty())return true; else return false; } int level(char p) { if(p=='+'||p=='-')return 1; if(p=='*'||p=='/')return 2; if(p=='^')return 3; return 0; } bool chfh() { for(int i=1;i<s.size();i++) if(level(s[i])>0&&level(s[i-1])>0) return false; return true; } //完成一次基本计算 void calc() { int m,n; char z; n=s1.top(); s1.pop(); m=s1.top(); s1.pop(); z=s2.top(); s2.pop(); switch(z) { case '+':s1.push(m+n);break; case '-':s1.push(m-n);break; case '*':s1.push(m*n);break; case '/':s1.push(m/n);break; default:s1.push(pow(m,n)); } return; } int main(){ cin>>s; s='('+s; if(s[s.size()-1]!='@'||!chkh()||!chfh()) { cout<<"NO\n"; return 0; } s[s.size()-1]=')'; int i=0; ch='('; do { if(ch=='(') { s2.push('('); } //遇到)就计算到(为止。遇到(之前,栈内所存运算符应该逐级上升,故需反向运算 //如1+2*3^4 else if(ch==')') { while(s2.top()!='(')calc(); s2.pop();//弹出( } else if(ch>='0'&&ch<='9'||ch=='-'&&s[i-1]=='(') //读到的是数字,把连续的数字变成数值 ,如果是'-'先判断前面是不是(,是则说明是负号不是减号 { if(ch=='-')x=0,y=-1;//是负号则符号设为-1,初始值为0 else x=ch-'0',y=1;//默认符号为正 ch0=s[++i]; while(ch0>='0'&&ch0<='9')x=x*10+ch0-'0',ch0=s[++i]; i--; x*=y; s1.push(x); } else //ch为运算符 { while(level(ch)<=level(s2.top()))//当前运算符不超过栈顶运算,先算栈顶运算 { calc(); } s2.push(ch);//直到当前运算符高于栈顶运算符再把运算符存栈 } }while(ch=s[++i]); cout<<s1.top()<<endl; return 0; }
第二章 队列
1332:【例2-1】周末舞会
#include<bits/stdc++.h> using namespace std; int main(){ std::ios::sync_with_stdio(false); int l,n,b[1000],g[1000],m,lh,lt,nh,nt,boy,girl; cin>>l>>n>>m; for(int i=1;i<=l;i++)b[i]=i; for(int i=1;i<=n;i++)g[i]=i; lh=nh=1; lt=l; nt=n; for(int i=1;i<=m;i++){ boy=b[lh++]; girl=g[nh++]; cout<<boy<<' '<<girl<<endl; b[++lt]=boy; g[++nt]=girl; } return 0; }
1333:【例2-2】Blah数集
#include<iostream> using namespace std; const int N=1000001; int main(){ int a,n,num=1; long long q[N],p[N]; //freopen("blash.in","r",stdin); while(cin>>a>>n) { q[1]=a; int s=1,two=1,tree=1; long long t; while(s<n){ long long t1=q[two]*2+1,t2=q[tree]*3+1; if(t1<t2){ t=t1; two++; } else if(t1>t2){ t=t2; tree++; } else { t=t1; two++; tree++; } q[++s]=t; } p[num++]=q[n]; } for(int i=1;i<num;i++) cout<<p[i]<<endl; return 0; }
1334:【例2-3】围圈报数
//1334:【例2-3】围圈报数 #include<iostream> using namespace std; int n,m,a[1000001][2]; int main() { cin>>n>>m; for(int i=1;i<=n;i++)a[i][0]=i,a[i][1]=i+1; a[n][1]=1; int pr=n,cu=1,num=0; while(n) { num++; if(num==m) { a[pr][1]=a[cu][1]; n--; num=0; cout<<a[cu][0]<<' '; } else pr=cu; cu=a[cu][1]; } return 0; }
1335:【例2-4】连通块
#include<iostream> using namespace std; int n,m,ans,tmp,a[110][110],que[110*110][2]; int fx[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; void bfs(int x,int y){ int head=0,tail=1,curx,cury; que[0][0]=x,que[0][1]=y; while(head<tail){ curx=que[head][0]; cury=que[head++][1]; for(int i=0;i<4;i++){ int tmpx=curx+fx[i][0]; int tmpy=cury+fx[i][1]; if(a[tmpx][tmpy]) { que[tail][0]=tmpx; que[tail++][1]=tmpy; a[tmpx][tmpy]=0; } } } } int main(){ //freopen("blacks.in","r",stdin); cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)cin>>a[i][j]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]){ ++ans; bfs(i,j); } cout<<ans<<endl; return 0; }
1359:围成面积
//1359:围成面积 #include<iostream> using namespace std; int const n=10,m=10; int a[n+2][m+2],ans; int dx[]={1,0,-1,0}; int dy[]={0,-1,0,1}; void dfs(int x,int y) { a[x][y]=1; for(int i=0;i<4;i++) { int tx=x+dx[i],ty=y+dy[i]; if(!a[tx][ty])dfs(tx,ty); } return; } int main(){ for(int i=0;i<=n+1;i++) for(int j=0;j<=m+1;j++)a[i][j]=-1; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)cin>>a[i][j]; for(int i=1;i<=n;i++) { if(!a[i][1])dfs(i,1); if(!a[i][m])dfs(i,m); } for(int i=2;i<m;i++) { if(!a[1][i])dfs(1,i); if(!a[n][i])dfs(n,i); } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(!a[i][j])ans++; cout<<ans; return 0; }
1360:奇怪的电梯(lift)
#include<bits/stdc++.h> using namespace std; int a[201],que[201],p[201],m[201]; int bfs(int n,int s,int b) { if(s==b)return 0; int h=0,t=0,cx,tx; que[0]=s,p[s]=1,m[s]=0; while(h<=t) { cx=que[h]; tx=cx+a[cx]; if(tx==b)return m[cx]+1; if(tx<=n&&p[tx]==0) { que[++t]=tx; m[tx]=m[cx]+1; p[tx]=1; } tx=cx-a[cx]; if(tx==b)return m[cx]+1; if(tx>0&&p[tx]==0) { que[++t]=tx; m[tx]=m[cx]+1; p[tx]=1; } h++; } return -1; } int main(){ int n,s,b; cin>>n>>s>>b; for(int i=1;i<=n;i++)cin>>a[i]; cout<<bfs(n,s,b); return 0; }
1361:产生数(Produce)
//1361:产生数(Produce) #include<iostream> using namespace std; int n,k,x1,x2,p[10000],gz[16][2],que[10000],ans=1; int f(int n,int x,int y)//把数n的倒数第x位换成y,如12345的倒数第2位换在6即得12365 { int t=1; for(int i=1;i<x;i++)t*=10; return n/10/t*10*t+y*t+n%t; } void bfs(int x) { que[0]=x; int h=0,t=0,cx,tx,tcx; while(h<=t) { cx=que[h]; for(int i=1;cx;i++) { tcx=cx%10;//tcx为cx的倒数第i位 for(int j=1;j<=k;j++) if(tcx==gz[j][0]) { tx=f(que[h],i,gz[j][1]); if(!p[tx])que[++t]=tx,p[tx]=1,ans++; } cx/=10; } h++; } return; } int main(){ cin>>n>>k; for(int i=1;i<=k;i++)cin>>gz[i][0]>>gz[i][1]; p[n]=1; bfs(n); cout<<ans<<endl; // for(int i=1;i<10000;i++) // if(p[i])cout<<i<<' '; return 0; }
1362:家庭问题(family)
#include<bits/stdc++.h> using namespace std; int a[101][101],p[101],gp,mx=1,cy,n;//gp家庭个数,cy家庭人数,mx最大家庭人数 void dfs(int x) { p[x]=1; for(int k=1;k<=n;k++) if(a[x][k]&&p[k]==0) { dfs(k); cy++; if(mx<=cy)mx=cy; } } int main() { int m,r,c; cin>>n>>m; for(int i=1;i<=m;i++) { cin>>r>>c; a[r][c]=a[c][r]=1; } for(int i=1;i<=n;i++) if(p[i]==0) { gp++; cy=1; dfs(i); } cout<<gp<<' '<<mx; return 0; }
1418:猴子选大王
第三章 树
第一节 二叉树
1336:【例3-1】找树根和孩子
//1336:【例3-1】找树根和孩子 #include<iostream> using namespace std; int mt[101]; //mt[x][0]记录x的儿子结点数,mt[x][1...]依次记录x的儿子结点 int n,m,x,y,maxx,maxn,num; int main(){ cin>>n>>m; for(int i=1;i<=m;i++) { cin>>x>>y; mt[y]=x; } for(int i=1;i<=n;i++) if(!mt[i]) { cout<<i<<endl; break; } for(int i=1;i<=n;i++) { num=0; for(int j=1;j<=n;j++) { if(mt[j]==i)num++; if(maxn<num)maxn=num,maxx=i; } } cout<<maxx<<endl; for(int i=1;i<=n;i++) if(mt[i]==maxx)cout<<i<<' '; return 0; }
1337:【例3-2】单词查找树
#include<bits/stdc++.h> using namespace std; string a[32770]; int main() { int n=0; while(cin>>a[++n]);//输入 n--; sort(a+1,a+n+1); int t=a[1].length(); for(int i=2;i<=n;i++) { int j=0; while(a[i][j]==a[i-1][j]&&j<a[i-1].length())j++; t+=a[i].length()-j; } cout<<t+1<<endl; return 0; }
1338:【例3-3】医院设置
//1338:【例3-3】医院设置 #include<iostream> #include<cstring> using namespace std; int a[101],p[101],t[101][101],x,l,r,n,minn,ans,sum; int main(){ memset(t,1,sizeof(t)); cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]>>l>>r; p[l]=p[r]=i; t[i][i]=0; if(l)t[i][l]=t[l][i]=1; if(r)t[i][r]=t[r][i]=1; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) for(int k=1;k<=n;k++) if(t[i][j]>t[i][k]+t[k][j]) t[i][j]=t[i][k]+t[k][j]; for(int i=1;i<=n;i++) { sum=0; for(int j=1;j<=n;j++) sum+=t[i][j]*a[j]; if(minn>sum||!minn)minn=sum,ans=i; } //cout<<ans<<endl; cout<<minn; return 0; }
//1338:【例3-3】医院设置(结构) #include<iostream> using namespace std; struct hp{ int num; int no; hp *pa; }tree[101],*p; int n,l,r,a[101],f[101][101],sum,minn=1e7; int main(){ cin>>n; for(int i=1;i<=n;i++) { cin>>tree[i].num>>l>>r; tree[i].no=i; if(l)tree[l].pa=&tree[i]; if(r)tree[r].pa=&tree[i]; } for(int i=2;i<=n;i++) { l=0; tree[1].pa=NULL; p=&tree[i]; while(1) { a[++l]=p->pa->no;//a[1...l]存储到根节点的路径 if(a[l]==1)break; else p=p->pa; } f[1][i]=f[i][1]=l; for(int j=2;j<=n;j++) { if(i==j)continue; r=0; p=&tree[j]; int g=1; while(g) { for(int k=1;k<=l;k++) if(p->no==a[k])//a[k]就是i结点和j结点的最早公共祖先 { f[i][j]=f[j][i]=k+r; g=0; break; } p=p->pa; r++; } } } for(int i=1;i<=n;i++)//穷举医院位置,擂台求最小值 { sum=0; for(int j=1;j<=n;j++) sum+=f[i][j]*tree[j].num; if(minn>sum||!minn)minn=sum; } cout<<minn; return 0; }
1339:【例3-4】求后序遍历
//1339:【例3-4】求后序遍历 #include<iostream> using namespace std; string s1,s2; int mf(string,char); void hx(int,int,int,int); int main(){ cin>>s1>>s2; int le=s1.size(); hx(0,le-1,0,le-1); return 0; } int mf(string x,char ch) { int len=x.size(); for(int i=0;i<len;i++) if(x[i]==ch)return i; return -1; } void hx(int b1,int e1,int b2,int e2) { int wz=mf(s2,s1[b1]); if(wz>b2)hx(b1+1,b1+wz-b2,b2,wz-1); if(wz<e2)hx(b1+wz-b2+1,e1,wz+1,e2); cout<<s1[b1]; }
1340:【例3-5】扩展二叉树
//1340:【例3-5】扩展二叉树 #include<bits/stdc++.h> using namespace std; struct node { char data; node *l,*r; }; char ch; node* creat(node *p) { ch=getchar(); if(ch=='.') p=NULL; else { p->data=ch; p->l=creat(new node); p->r=creat(new node); } return p; } void przx(node *p) { if(p!=NULL) { przx(p->l); cout<<p->data; przx(p->r); } return ; } void prhx(node *p) { if(p!=NULL) { prhx(p->l); prhx(p->r); cout<<p->data; } return ; } int main() { node *q,n; q=&n; q=creat(q); przx(q); cout<<endl; prhx(q); return 0; }
1363:小球(drop)
//1363:小球(drop) #include<iostream> using namespace std; int const n=1<<20+1; bool tree[n]; int d,l,ans; int main(){ cin>>d>>l; for(int i=1;i<=l;i++) { ans=1; for(int j=1;j<d;j++) { if(tree[ans]) { tree[ans]=false; ans=ans*2+1; } else { tree[ans]=true; ans=ans*2; } } } cout<<ans; return 0; }
1364:二叉树遍历(flist)
//1364:二叉树遍历(flist) #include<iostream> #include<cstdio> using namespace std; string s1,s2; int ba[255],ab[255]; void calc(int l,int r) { if(l>r)return; int dw,maxx=300; for(int i=l;i<=r;i++) if(maxx>ab[i])maxx=ab[i]; cout<<s2[maxx]; dw=ba[maxx]; calc(l,dw-1); calc(dw+1,r); } int main(){ cin>>s1>>s2; int len=s1.size()-1; for(int i=0;i<=len;i++) for(int j=0;j<=len;j++) if(s1[i]==s2[j])ab[i]=j,ba[j]=i; calc(0,len); return 0; }
1365:FBI树(fbi)
#include<iostream> #include<cstdio> using namespace std; int c[10]; struct node { char ch; node *l,*r; }; node tree[10000]; int n,t,a,b; string s; char t1,t2; void pr( node *p) { if(p) { pr(p->l); pr(p->r); cout<<p->ch; } } int main(){ cin>>n>>s; c[0]=1; for(int i=1;i<=n+1;i++)c[i]=c[i-1]*2; for(int i=c[n];i<c[n+1];i++) tree[i].ch=s[i-c[n]]=='1'?'I':'B'; for(int i=c[n]-1;i>=1;i--) { tree[i].l=&tree[i*2]; tree[i].r=&tree[i*2+1]; t1=tree[i].l->ch; t2=tree[i].r->ch; if(t1!=t2||t1=='F'&&t2=='F')tree[i].ch='F'; else if(t1==t2&&t1=='B')tree[i].ch='B'; else tree[i].ch='I'; } // for(int i=1;i<c[n+1];i++) // cout<<i<<':'<<tree[i].ch<<endl; pr(&tree[1]); return 0; }
1366:二叉树输出(btout)
//1366:二叉树输出(btout) #include<iostream> #include<cstdio> using namespace std; string s1,s2; int a[256],b[256],c[256],n; struct node { int no,tot; char va; node *l,*r; }; node tree[256],*p; void build(int x1,int y1,int x2,int y2) { if(x1==y1)return; int wz=a[x1]; if(wz>x2) { tree[x1].l=&tree[x1+1]; build(x1+1,x1+wz-x2,x2,wz-1); } if(x1+wz-x2<y1) { tree[x1].r=&tree[x1+wz-x2+1]; build(x1+wz-x2+1,y1,wz+1,y2); } } int calc(node *q) { q->tot=0; if(q->l)q->tot+=calc(q->l); if(q->r)q->tot+=calc(q->r); if(!q->tot)q->tot=1; return q->tot; } void pr(node *q) { if(q) { for(int i=0;i<q->tot;i++) cout<<q->va; cout<<endl; pr(q->l); pr(q->r); } } int main(){ cin>>s1>>s2; n=s1.size(); for(int i=0;i<n;i++) tree[i].va=s1[i],tree[i].no=i; for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(s1[i]==s2[j]) a[i]=j,b[j]=i; node *q=&tree[0]; build(0,n-1,0,n-1); calc(q); pr(tree); return 0; }
1367:查找二叉树(tree_a)
//1367:查找二叉树(tree_a) #include<iostream> using namespace std; struct node { int num; node *l,*r; }; node tree[101]; int n,x,l,r,ans; void pr(node *p) { if(p) { pr(p->l); ans++; if(p->num==x) { cout<<ans; return; } pr(p->r); } } int main(){ cin>>n>>x; for(int i=1;i<=n;i++) { cin>>tree[i].num>>l>>r; if(l)tree[i].l=&tree[l]; if(r)tree[i].r=&tree[r]; } pr(&tree[1]); return 0; }
1368:对称二叉树(tree_c)
//1368:对称二叉树(tree_c) #include<iostream> #include<cstdio> using namespace std; string s; int n,ans; int main(){ cin>>s; n=s.size(); ans=(n+1)%2; for(int i=1;i<n-1;i+=2) { if(ans)break; ans=(s[i]=='#')^(s[i+1]=='#'); } if(ans)cout<<"No"; else cout<<"Yes"; return 0; }
第二节 堆及其应用
1369:合并果子(fruit)
#include<bits/stdc++.h> using namespace std; priority_queue<int,vector<int>,greater<int> >a; int main() { int n,tmp; cin>>n; for(int i=1;i<=n;i++) { cin>>tmp; a.push(tmp); } int ans=0; while(!a.empty()) { int s1=a.top(); a.pop(); if(a.empty())break; else { int s2=a.top(); a.pop(); ans+=s1+s2; a.push(s1+s2); } } cout<<ans; return 0; }
1370:最小函数值(minval)
#include<bits/stdc++.h> using namespace std; priority_queue<int,vector<int>,less<int> >q; priority_queue<int,vector<int>,greater<int> >w; int main() { int n,m,a,b,c,tmp,maxx; cin>>n>>m; cin>>a>>b>>c; for(int j=1;j<=m;j++) { tmp=a*j*j+b*j+c; q.push(tmp); } for(int i=1;i<n;i++) { cin>>a>>b>>c; maxx=q.top(); for(int k=1;k<=m;k++) { int heap=a*k*k+b*k+c; if(heap<maxx) { q.pop(); q.push(heap); maxx=q.top(); } else break; } } for(int i=1;i<=m;i++) { int tr=q.top(); q.pop(); w.push(tr); } for(int i=1;i<=m;i++) { int dd=w.top(); w.pop(); cout<<dd<<" "; } return 0; }
1371:看病
//1371:看病 #include<iostream> #include<cstdio> using namespace std; struct node{ char name[25]; int num; }heap[100001],tmp; char zl[5]; int n,hs; void put(node d) { int now=++hs,next; heap[hs]=d; while(now>1) { next=now>>1; if(heap[now].num<=heap[next].num)return; swap(heap[now],heap[next]); now=next; } return; } void get() { if(hs)printf("%s %d\n",heap[1].name,heap[1].num); else { printf("none\n"); return; } int now=1,next=2; heap[1]=heap[hs--]; while(next<=hs) { if(next<hs&&heap[next].num<heap[next+1].num)next++; if(heap[next].num<heap[now].num)break; swap(heap[next],heap[now]); now=next; next=now<<1; } } int main(){ cin>>n; for(int i=1;i<=n;i++) { scanf("%s",zl); if(zl[1]=='o')get(); else { scanf("%s %d",&tmp.name,&tmp.num); put(tmp); } } return 0; }
1372:小明的账单
//1372:小明的账单 #include<iostream> #include<set> #include<cstdio> using namespace std; int n,m,x; multiset<int> zd; int main() { cin>>n; for(int i=1;i<=n;i++) { scanf("%d",&m); for(int j=1;j<=m;j++) { scanf("%d",&x); zd.insert(x); } printf("%d %d\n",*zd.begin(),*(--zd.end())); zd.erase(zd.begin()); zd.erase(--zd.end()); } return 0; }
1373:鱼塘钓鱼(fishing)
#include<bits/stdc++.h> #define fish first #define lake second using namespace std; priority_queue<pair<int,int> >heap; int f[105]; int t[105]; int d[105]; int main() { int n; cin>>n; for(int i=1;i<=n;i++) cin>>f[i]; for(int i=1;i<=n;i++) cin>>d[i]; for(int i=1;i<n;i++) cin>>t[i]; int m; cin>>m; int T=0; int t1=0; int ans=0; int maxn=0; for(int k=1;k<=n;k++){//枚举最远走到的池塘的编号 T=m-t1;//计算剩余的时间 ans=0; while(!heap.empty()) { heap.pop(); } for(int i=1;i<=k;i++) {//收集能够钓鱼的池塘治疗 heap.push(make_pair(f[i],i)); } while(T>0&&heap.top().fish>0) { pair<int ,int >a=heap.top(); heap.pop(); ans+=a.fish;//贪心取鱼最多的池塘 a.fish-=d[a.lake];//修改鱼的数量 heap.push(a);//维护堆 T--;//剩余时间变少 } if(ans>maxn) maxn=ans;//刷新最优解 t1+=t[k];//累计走路需要的时间 } cout<<maxn<<endl; return 0; }
第四章 图论算法
第一节 图的遍历
1341:【例题】一笔画问题
//1341:【例题】一笔画问题 #include<bits/stdc++.h> using namespace std; int mapp[1005][1005]; int n,m; int s[105]; int c=0; int num[2005]; void dfs(int i) { for(int j=1; j<=n; j++) { if(mapp[i][j]==1) { mapp[i][j]=mapp[j][i]=0; dfs(j); } } num[++c]=i; } int main() { memset(mapp,0,sizeof(mapp)); cin>>n>>m; int a,b; for(int i=1; i<=m; i++) { cin>>a>>b; mapp[a][b]=mapp[b][a]=1; s[a]++; s[b]++; } int flag=1; for(int i=1; i<=n; i++) { if(s[i]%2==1) { flag=i; } } dfs(flag); for(int i=1; i<=c; i++) { cout<<num[i]<<" "; } cout<<endl; return 0; }
1374:铲雪车(snow)
//铲雪车 #include<iostream> #include<cmath> using namespace std; int main() { long long int sx,sy,x1,y1,x2,y2; double s=0; cin>>sx>>sy; while(cin>>x1>>y1>>x2>>y2) { s+=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } long long int h=s/10000; long long int f=(s/10000-h)*60+0.5; cout<<h<<':'; if(f<10)cout<<'0'; cout<<f<<endl; return 0; }
1375:骑马修栅栏(fence)
#include<bits/stdc++.h> using namespace std; int n; int maxn; int beginn=10000; int mapp[1000][1000]; int path[1000]; int d[1000]; int start=0; int cnt=0; void dfs(int i) { for(int j=beginn;j<=maxn;j++){ if(mapp[i][j]){ mapp[i][j]--; mapp[j][i]--; dfs(j); } } path[++cnt]=i; } int main() { ios::sync_with_stdio(false); cin>>n; for(int i=0;i<n;i++){ int x,y; cin>>x>>y; mapp[x][y]++;//说明x和y有连边,这里++是因为俩个点之间可以不止一个栅栏 mapp[y][x]++; d[x]++;//统计每点的度 d[y]++; beginn=min(min(x,y),beginn);//这个是找到最小的点 maxn=max(max(x,y),maxn);//这个是找点 } for(int i=beginn;i<=maxn;i++){//注意这是从点的的度来找的,找奇点 if(d[i]%2){ start=i; break; } } if(start==0) start=beginn;//如果没有找到奇点那么就从最小的点开始遍历 dfs(start); for(int i=cnt;i>=1;i--){ cout<<path[i]<<endl; } return 0; }
第二节 最短路径算法
1342:【例4-1】最短路径问题
//1342:【例4-1】最短路径问题 //dijkstra算法 #include<iostream> #include<cstring> #include<iomanip> #include<cmath> using namespace std; const int maxx=0x7fffffff; int n,m,p[101][2],l[101][101],que[301]; double d[101],f[101][101],ans; bool q[101]; int main() { int a,b,x,y,s,e; double minx=maxx; cin>>n; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[i][j]=maxx; for(int i=1;i<=n;i++) { f[i][i]=0; d[i]=0x7fffffff; q[i]=false; cin>>p[i][0]>>p[i][1]; } cin>>m; for(int i=1;i<=m;i++) { cin>>a>>b; x=p[a][0]-p[b][0]; y=p[a][1]-p[b][1]; f[b][a]=f[a][b]=sqrt(x*x+y*y); l[a][0]++,l[b][0]++; l[a][l[a][0]]=b,l[b][l[b][0]]=a; } cin>>s>>e; d[s]=0; int head=1,tail=1,tx,cx; que[1]=s; while(head<=tail) { cx=que[head++]; q[cx]=false; for(int i=1;i<=l[cx][0];i++) { tx=l[cx][i]; //cout<<"cx:"<<cx<<'-'<<tx<<' '<<f[tx][cx]<<endl; if(d[tx]>d[cx]+f[tx][cx]) { d[tx]=d[cx]+f[tx][cx]; if(!q[tx])que[++tail]=tx,q[tx]=true; } } } ans=d[e]; cout<<fixed<<setprecision(2)<<ans<<endl; return 0; }
1343:【例4-2】牛的旅行
//1343:【例4-2】牛的旅行 #include<iostream> #include<cmath> #include<iomanip> using namespace std; const int maxn=0x3fffffff; const int N=151; int pt[N][2],n; double s[N][N],f[N][N],d[N],ans; /*pt数组存储点的坐标,s数组存储任两点间的距离 f数组存储任两点间的最短路径长,d数组存储到某点的最大路径长 (若两点不相连通则该值为0)*/ int main() { int x,y; char tx; cin>>n; //输入点的坐标 for(int i=1;i<=n;i++)cin>>pt[i][0]>>pt[i][1]; //输入邻接表 for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { cin>>tx; x=pt[i][0]-pt[j][0]; y=pt[i][1]-pt[j][1]; s[j][i]=s[i][j]=sqrt(x*x+y*y); //若两点连通则路径长等于两点间距离,否则无穷大 if(tx=='1'||i==j)f[i][j]=f[j][i]=s[i][j]; else f[i][j]=f[j][i]=maxn; } //弗洛伊德法求两点间的最小路径长 for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(f[i][j]>f[i][k]+f[j][k]) f[i][j]=f[i][k]+f[j][k]; //求与i点连通的点到i点的最大距离d[i] for(int i=1;i<=n;i++)d[i]=0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(f[i][j]<maxn-1&&d[i]<f[i][j])d[i]=f[i][j]; //f[i][j]>maxn-1意味着i,j两个点位于两个不同牧场 //如果连通ij合成一个大的牧场,新牧场直径为 d[i]+d[j]+s[i][j] ans=maxn; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(f[i][j]>maxn-1&&ans>d[i]+d[j]+s[i][j]) ans=d[i]+d[j]+s[i][j]; //新牧场直径不可能比原来牧场直径小 for(int i=1;i<=n;i++)if(d[i]>ans)ans=d[i]; cout<<fixed<<setprecision(6)<<ans<<endl; return 0; }
1344:【例4-4】最小花费
//1344:【例4-4】最小花费 #include<iostream> #include<cmath> #include<iomanip> using namespace std; const int maxn=0x3fffffff; const int N=2001; int n,m,d[N],msg[N][N],p[N]; double ss[N],f[N][N]; double ans; /*dijkstra算法*/ int main() { int a,b,c,s,e,tmp; double maxx; cin>>n>>m; //处理任两人间转账实收比例 for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[i][j]=f[j][i]=0; for(int i=1;i<=m;i++) { cin>>a>>b>>c; f[a][b]=f[b][a]=1-c/100.0; msg[a][0]++,msg[b][0]++; msg[a][msg[a][0]]=b,msg[b][msg[b][0]]=a; } cin>>s>>e; //弗洛伊德法求两人间最大实收比例 // for(int k=1;k<=n;k++) // for(int i=1;i<=n;i++) // for(int j=1;j<=n;j++) // if(f[i][j]<f[i][k]*f[j][k]) // f[i][j]=f[i][k]*f[j][k]; for(int i=1;i<=n;i++)ss[i]=f[s][i]; ss[s]=1; p[s]=1; while(1) { tmp=0; maxx=0; for(int i=1;i<=n;i++) if(p[i]==0&&maxx<ss[i]) maxx=ss[i],tmp=i; if(tmp==0)break; p[tmp]=1; for(int i=1;i<=msg[tmp][0];i++) { int tt=msg[tmp][i]; if(ss[tt]<ss[tmp]*f[tt][tmp])ss[tt]=ss[tmp]*f[tt][tmp]; } } ans=100/ss[e]; cout<<fixed<<setprecision(8)<<ans<<endl; return 0; }
1345:【例4-6】香甜的黄油
//1345:【例4-6】香甜的黄油 #include<iostream> #include<cstring> //memset须用 using namespace std; const int N=2001; int p[N],f[N],d[N][N],msg[N][N],ans,tot=0x7fffffff,c,n,m; int bz[N],que[N*2],h,t=1; int main() { int x,y,s; memset(d,0x3f,sizeof(d)); cin>>c>>n>>m; for(int i=1;i<=c;i++)cin>>p[i]; for(int i=1;i<=m;i++) { cin>>x>>y>>s; d[i][i]=0; d[x][y]=d[y][x]=s; msg[x][++msg[x][0]]=y; msg[y][++msg[y][0]]=x; } // for(int k=1;k<=n;k++)//弗洛伊德求最小距离 (超时) // for(int i=1;i<=n;i++) // for(int j=1;j<=n;j++) // if(d[i][j]>d[i][k]+d[j][k])d[i][j]=d[i][k]+d[j][k]; //以下采用SPFA算法求到i牧场的最小距离 //f[j]为i,j两牧场的最小距离 ,bz[j]标识j是否在队列中 for(int i=1;i<=n;i++)//暴力枚举放置点 { for(int j=1;j<=n;j++)f[j]=0x3fffffff,bz[j]=0; f[i]=0,t=1,h=0,que[1]=i; do { h=h%1601+1;//采用循环队列 x=que[h],bz[x]=0; for(int j=1;j<=msg[x][0];j++) { s=msg[x][j]; if(f[s]>f[x]+d[x][s]) { f[s]=f[x]+d[x][s]; if(bz[s]==0) { t=t%1601+1; que[t]=s,bz[s]=1; } } } }while(h!=t); s=0; for(int j=1;j<=c;j++)s+=f[p[j]]; if(tot>s)tot=s; } // for(int i=1;i<=n;i++) // { // for(int j=1;j<=n;j++) // cout<<d[i][j]<<' '; // cout<<p[i]<<endl; // } cout<<tot<<endl; return 0; }
1376:信使(msner)
//1376:信使(msner) #include<iostream> using namespace std; const int maxn=1e8; const int N=101; int d[N][N],ms[N][N],p[N],f[N],n,m,ans; int main() { ios::sync_with_stdio(0); int x,y,s; cin>>n>>m; for(int i=1;i<=n;i++)p[i]=0,f[i]=maxn; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) d[i][j]=maxn; for(int i=1;i<=m;i++) { cin>>x>>y>>s; ms[x][++ms[x][0]]=y; ms[y][++ms[y][0]]=x; d[x][y]=d[y][x]=s; } for(int i=1;i<=ms[1][0];i++)f[ms[1][i]]=d[1][ms[1][i]]; f[1]=0,p[1]=1; for(int i=1;i<n;i++) { s=0; x=maxn; for(int j=2;j<=n;j++) { if(p[j]==0&&f[j]<x) { x=f[j]; s=j; } } if(s==0)break; p[s]=1; for(int j=1;j<=ms[s][0];j++) { y=ms[s][j]; if(p[y]==0&&f[y]>f[s]+d[s][y])f[y]=f[s]+d[s][y]; } } ans=0; for(int i=2;i<=n;i++) if(ans<f[i])ans=f[i]; if(ans==maxn)ans=-1; cout<<ans<<endl; return 0; }
1377:最优乘车(travel)
//1377:最优乘车(travel) #include<iostream> #include<cstdio> using namespace std; const int N=501; const int maxn=1e9; string str; int link[N][N],msg[N][N],dis[N],p[N],n,m,cnt,x; int main() { //ios::sync_with_stdio(0); cin>>m>>n; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i==j)link[i][i]=0; else link[i][j]=maxn; for(int i=1;i<=m;i++) { cnt=0,x=0; char ch='\0'; while(ch<'0'||ch>'9')ch=getchar(); do { if(ch>='0'&&ch<='9')x=x*10+ch-'0'; if(ch=='\n'||ch==' ') { if(x)p[++cnt]=x,x=0; if(ch=='\n')break; } ch=getchar(); }while(1); for(int j=1;j<cnt;j++)//同一线路前面站到后面站就一次搞定 { int x=p[j]; for(int k=j+1;k<=cnt;k++) { int y=p[k]; msg[x][++msg[x][0]]=y,link[x][y]=1; //此处非双向 } } } for(int k=1;k<=n;k++)//弗洛伊德求最小距离 for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(link[i][j]>link[i][k]+link[k][j]) link[i][j]=link[i][k]+link[k][j]; //SPFA算法求最小距离 // for(int i=2;i<=n;i++)dis[i]=link[1][i],p[i]=0; // dis[1]=0,p[1]=1; // for(int i=1;i<=n;i++) // { // x=maxn; // cnt=0; // for(int j=2;j<=n;j++) // if(p[j]==0&&x>dis[j]) // x=dis[j],cnt=j; // if(cnt==0)break; // p[cnt]=1; // for(int j=1;j<=msg[cnt][0];j++) // { // x=msg[cnt][j]; // if(dis[x]>link[cnt][x]+dis[cnt]) // dis[x]=link[cnt][x]+dis[cnt]; // } // } // for(int i=1;i<=n;i++) // { // for(int j=1;j<=n;j++) // cout<<link[i][j]<<' '; // cout<<dis[i]<<endl; // } // if(dis[n]!=maxn)cout<<dis[n]-1<<endl; // else cout<<"N0\n"; if(link[1][n]==maxn)cout<<"NO\n"; else cout<<link[1][n]-1<<endl; return 0; }
1378:最短路径(shopth)
//1378:最短路径(shopth) #include<iostream> #include<cstdio> using namespace std; const int N=81; const int inf=1e9; int link[N][N],msg[N][N],dis[N],p[N],n,s; //msg[x][y]存储以x为起点的边信息,msg[x][0]存储边的条数,其后依次存储各边终点 int que[N*2+3],h=0,t=1,cx,tx; int read() { int x=0,f=1,cnt=0; //cnt记录输入的数字个数,若为0则说明只输入了一个-(无边) char ch='\0'; while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); do { if(ch=='-')f=-1; else cnt++,x=x*10+ch-'0'; ch=getchar(); }while(ch>='0'&&ch<='9'); if(cnt==0)x=inf; else x*=f; return x; } int get(string s0) { if(s0=="-")return inf; int f=1,x=0; for(int i=0;i<s0.length() ;i++) { if(s0[i]=='-')f=-1; else x=x*10+s0[i]-'0'; } return x*f; } int main() { //ios::sync_with_stdio(0); cin>>n>>s; string ss; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { cx=read(); //cin>>ss; link[i][j]=cx; if(i!=j&&cx<inf)msg[i][++msg[i][0]]=j; } //因为有负权边,不可用dijkstra,故采用SPFA for(int j=1;j<=n;j++)dis[j]=inf,p[j]=0; dis[s]=0,h=0,t=1,que[1]=s; while(h!=t)//队列中最多n个元素,不可能队满,h=t则说明队空 { h=h%(N*2)+1;//用循环队列 cx=que[h],p[cx]=0; for(int j=1;j<=msg[cx][0];j++) { tx=msg[cx][j]; if(dis[tx]>dis[cx]+link[cx][tx])//tx的值因cx而更新 { dis[tx]=dis[cx]+link[cx][tx];//更新tx的值 if(p[tx]==0)//如果tx没在队列中则让tx入队 t=t%(N*2)+1,que[t]=tx,p[tx]=1; } } } // for(int k=1;k<=n;k++) // for(int i=1;i<=n;i++) // for(int j=1;j<=n;j++) // if(link[i][j]>link[i][k]+link[k][j]) // link[i][j]=link[i][k]+link[k][j]; for(int i=1;i<=n;i++) if(i!=s)cout<<'('<<s<<" -> "<<i<<") = "<<dis[i]<<endl; return 0; }
1379:热浪(heatwv)
//1379:热浪(heatwv) #include<iostream> using namespace std; int a[2501][2501],b[2501][2501],c[2501],p[2501]; int T,C,Ts,Te; void dfs(int x) { if(x==Ts)return; int t; for(int i=1;i<=b[x][0];i++) { t=b[x][i]; if(p[t])continue; if(c[x]+a[x][t]<c[t]||0==c[t]) { c[t]=c[x]+a[x][t]; p[t]=1; dfs(t); p[t]=0; } } } int main(){ int Rs,Re,Ci,tmp; cin>>T>>C>>Ts>>Te; for(int i=1;i<=C;i++) { cin>>Rs>>Re>>Ci; if(a[Rs][Re]==0||a[Rs][Re]>Ci) { if(a[Rs][Re]==0) { b[Re][0]++; tmp=b[Re][0]; b[Re][tmp]=Rs; b[Rs][0]++; tmp=b[Rs][0]; b[Rs][tmp]=Re; } a[Rs][Re]=a[Re][Rs]=Ci; } } p[Te]=1; dfs(Te); cout<<c[Ts]<<endl; return 0; }
1380:分糖果(candy)
//1380:分糖果(candy) #include<bits/stdc++.h> using namespace std; const int N=1e5+1; const int inf=1e9; int link[N*200][2],last[N],dis[N],mk[N],que[N*2+2]; int ans,n,p,c,tt,x,y,cnt,h,t=1,cx,tx; void init(int x,int y) { link[++cnt][0]=last[x]; link[cnt][1]=y; last[x]=cnt; } int main() { ios::sync_with_stdio(0); cin>>n>>p>>c>>tt; for(int i=1;i<=p;i++) { cin>>x>>y; init(x,y); init(y,x); } for(int i=1;i<=n;i++)dis[i]=inf,mk[i]=0; dis[c]=0,que[1]=c; while(h!=t) { h=h%(N*2)+1; cx=que[h],mk[cx]=0; for(int i=last[cx];i;i=link[i][0]) { tx=link[i][1]; if(dis[tx]>dis[cx]+1) { dis[tx]=dis[cx]+1; if(mk[tx]==0)t=t%(N*2)+1,que[t]=tx,mk[tx]=1; } } } ans=0; for(int i=1;i<=n;i++)if(ans<dis[i])ans=dis[i]; cout<<ans+tt+1<<endl; return 0; }
1381:城市路(Dijkstra)
//1381:城市路(Dijkstra) #include<iostream> using namespace std; const int inf=1e9; const int N=2001; int last[N],dis[N],mk[N],n,m,a,b,c,cnt,maxn,tx; struct{ int next,to,s; }link[20005]; void init(int x,int y,int z) { link[++cnt].next=last[x]; link[cnt].to=y; link[cnt].s=z; last[x]=cnt; } int main() { ios::sync_with_stdio(0); cin>>n>>m; for(int i=1;i<=m;i++) { cin>>a>>b>>c; init(a,b,c); init(b,a,c); } for(int i=2;i<=n;i++)dis[i]=inf,mk[i]=0; for(int i=1;i<n;i++) { maxn=inf,tx=0; for(int j=1;j<=n;j++) if(mk[j]==0&&maxn>dis[j])maxn=dis[j],tx=j; if(tx==0)break; mk[tx]=1; for(int j=last[tx];j;j=link[j].next) { int x=link[j].to; if(dis[x]>dis[tx]+link[j].s) dis[x]=dis[tx]+link[j].s; } } cout<<dis[n]<<endl; return 0; }
1382:最短路(Spfa)
//1382:最短路(Spfa) #include<iostream> using namespace std; const int N=1e5+1; const int inf=1e9; struct link{ int pre,to,s; }f[N*10]; int dis[N],mk[N],last[N],que[N*2+2],n,m,cnt; void init(int x,int y,int z) { cnt++; f[cnt].pre=last[x]; f[cnt].to=y; f[cnt].s=z; last[x]=cnt; } int main() { ios::sync_with_stdio(0); cin>>n>>m; int a,c,b; for(int i=1;i<=m;i++) { cin>>a>>b>>c; init(a,b,c); init(b,a,c); } int h=0,t=1,cx,tx; for(int i=1;i<=n;i++)dis[i]=inf,mk[i]=0; que[1]=1,dis[1]=0; while(h!=t) { h=h%(N*2)+1; cx=que[h],mk[cx]=0; for(int i=last[cx];i;i=f[i].pre) { tx=f[i].to; if(dis[tx]>dis[cx]+f[i].s) { dis[tx]=dis[cx]+f[i].s; if(mk[tx]==0) t=t%(N*2)+1,que[t]=tx,mk[tx]=1; } } } cout<<dis[n]<<endl; return 0; }
1419:SPFA(II)
//1419:SPFA(II) #include<iostream> using namespace std; const int N=2e4+1; const long long inf=1e16; struct link{ int pre,to,s; }f[N*4]; long long dis[N]; int mk[N],last[N],que[N*2+2],n,m,cnt; void init(int x,int y,int z) { cnt++; f[cnt].pre=last[x]; f[cnt].to=y; f[cnt].s=z; last[x]=cnt; } int main() { ios::sync_with_stdio(0); cin>>n>>m; int a,c,b; for(int i=1;i<=m;i++) { cin>>a>>b>>c; init(a,b,c); } int h=0,t=1,cx,tx; for(int i=1;i<=n;i++)dis[i]=inf,mk[i]=0; que[1]=1,dis[1]=0; while(h!=t) { h=h%(N*2)+1; cx=que[h],mk[cx]=0; for(int i=last[cx];i;i=f[i].pre) { tx=f[i].to; if(dis[tx]>dis[cx]+f[i].s) { dis[tx]=dis[cx]+f[i].s; if(mk[tx]==0) t=t%(N*2)+1,que[t]=tx,mk[tx]=1; } } } cout<<dis[n]<<endl; return 0; }
1420:Dijkastra(II)
//1420:Dijkastra(II) #include<iostream> using namespace std; const int N=2e5+1; const long long inf=1e16; struct link { int pre,to,s; }f[N*40]; long long dis[N],heap[N]; int n,m,a,b,c,cnt,last[N],pos[N],hp; //int mk[N],maxn,cx,tx; //堆heap中存储占的编号,pos中存储点的在堆中位置 void init(int x,int y,int z) { f[++cnt].pre=last[x]; f[cnt].to=y; f[cnt].s=z; last[x]=cnt; } void update(int x)//x为节点编号 { int now=pos[x],next,a,b;//从now位置向上更新 while(now>1) { next=now>>1;//next为now的父节点 a=heap[now],b=heap[next]; if(dis[a]>dis[b])break; heap[now]=b,heap[next]=a;//交换堆中两数的值 pos[a]=next,pos[b]=now;//同步更新两节点在堆中位置 now=next; } } void put(int x)//x为节点编号 { heap[++hp]=x; pos[x]=hp; update(x); } int get() { int x=heap[1]; heap[1]=heap[hp--]; int now=1,next,a,b;//从now位置向下更新 while(now*2<=hp) { next=now<<1;//next为now的左子节点 if(next<hp&&dis[heap[next+1]]<dis[heap[next]])next++; //如果now的右子节点比左子节点还小,则右子节点更有可能成为新的父节点 a=heap[now],b=heap[next]; if(dis[a]<dis[b])break; heap[now]=b,heap[next]=a; pos[a]=next,pos[b]=now; now=next; } return x; } int main() { ios::sync_with_stdio(0); cin>>n>>m; for(int i=1;i<=m;i++) { cin>>a>>b>>c; init(a,b,c); init(b,a,c); } dis[1]=0; for(int i=2;i<=n;i++)dis[i]=inf; put(1); // for(int i=last[1];i;i=f[i].pre ) // { // tx=f[i].to; // if(dis[tx]>f[i].s)//可能有重边 // dis[tx]=f[i].s; // } while(hp)//hp为堆容量 { int x=get(); pos[x]=0;//pos[x]=0表示x己出堆 if(x==n)break;//n处于堆顶,n己变为白点,不会再更新 for(int i=last[x];i;i=f[i].pre ) { int y=f[i].to; if(dis[y]>dis[x]+f[i].s) { dis[y]=dis[x]+f[i].s; if(pos[y]==0)put(y); else update(y);//dis[y]的值变小,y在堆中位置只会向上走 } } } // for(int i=1;i<n;i++)//普通dijkstra算法超时,须用堆优化 // { // maxn=inf,cx=0; // for(int j=2;j<=n;j++) // if(mk[j]==0&&maxn>dis[j]) // maxn=dis[j],cx=j; // if(cx==0)break; // mk[cx]=1; // for(int j=last[cx];j;j=f[j].pre) // { // tx=f[j].to; // if(dis[tx]>dis[cx]+f[j].s) // dis[tx]=dis[cx]+f[j].s; // } // } cout<<dis[n]<<endl; return 0; }
1421:Floyd
//1421:Floyd #include<iostream> using namespace std; const int N=501; const long long inf=1e16; int n,m; long long dis[N][N],s; int main() { ios::sync_with_stdio(0); long long a,b,c; cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i==j)dis[i][j]=0; else dis[i][j]=inf; for(int i=1;i<=m;i++) { cin>>a>>b>>c; if(dis[a][b]>c) dis[a][b]=c; } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(dis[i][j]>dis[i][k]+dis[k][j]) //后面两条件若不加,则可以因为负权边把本不连通的边算成连通的边 dis[i][j]=dis[i][k]+dis[k][j]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(dis[i][j]>1e13)dis[i][j]=inf; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) s^=dis[i][j]+inf; cout<<s<<endl; return 0; }
第三节 图的连通性问题
1383:刻录光盘(cdrom)
//1383:刻录光盘(cdrom) #include<iostream> using namespace std; const int N=201; bool link[N][N]; int fa[N],n,ans,x; int main() { ios::sync_with_stdio(0); cin>>n; for(int i=1;i<=n;i++) { fa[i]=i; cin>>x; while(x) { link[i][x]=true; cin>>x; } } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) link[i][j]=link[i][j]||link[i][k]&&link[k][j]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(link[i][j])fa[j]=fa[i]; for(int i=1;i<=n;i++)if(fa[i]==i)ans++; cout<<ans<<endl; return 0; }
1384:珍珠(bead)
#include<iostream> using namespace std; const int N=100; bool h[N][N],q[N][N]; int a[N],b[N],n,m,ans; int main() { ios::sync_with_stdio(0); int x,y; cin>>n>>m; for(int i=1;i<=m;i++) { cin>>x>>y; h[x][y]=q[y][x]=true; } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { h[i][j]=h[i][j]||h[i][k]&&h[k][j]; q[i][j]=q[i][j]||q[i][k]&&q[k][j]; } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) { if(h[k][i])a[k]++; if(q[k][i])b[k]++; } for(int i=1;i<=n;i++) if(a[i]>=(n+1)/2||b[i]>=(n+1)/2)ans++; cout<<ans<<endl; return 0; }
第四节 并查集
1346:【例4-7】亲戚(relation)
#include <iostream> #include <cstdio> using namespace std; int n,m,f[200001]; int findx(int x) { return f[x]==x?x:f[x]=findx(f[x]); } void uni(int x,int y) { int r1=findx(x),r2=findx(y); if(r1!=r2)f[r2]=r1; } int main() { int i,j,x,y; ios::sync_with_stdio(0); cin.tie(0); cin>>n>>m; //scanf("%d %d",&n,&m); for(i=1; i<=n; i++) f[i]=i; for(i=1; i<=m; i++) { // scanf("%d%d",&x,&y); cin >> x >> y; uni(x,y); } cin>>m; for(i=1; i<=m; i++) { // scanf("%d%d",&x,&y); cin >> x >> y; if(findx(x)==findx(y)) //printf("Yes\n"); cout<<"Yes\n"; else //printf("No\n"); cout<<"No\n"; } return 0; }
1347:【例4-8】格子游戏
#include <iostream> using namespace std; struct node { int x,y;}f[301][301],k1,k2; int i,j,m,n,x,y; char c; node root(node k) { if((f[k.x][k.y].x==k.x)&&(f[k.x][k.y].y==k.y))return k; f[k.x][k.y]=root(f[k.x][k.y]); return f[k.x][k.y]; } int main() { cin>>n>>m; for(i=1;i<=n;i++) for(j=1;j<=n;j++) {f[i][j].x=i;f[i][j].y=j;} for(i=1;i<=m;i++) { cin>>x>>y>>c; if(c=='D') {k1=root(f[x][y]);k2=root(f[x+1][y]);} if(c=='R') {k1=root(f[x][y]);k2=root(f[x][y+1]);} if((k1.x==k2.x)&&(k1.y==k2.y)) {cout<<i<<endl;return 0;} else f[k1.x][k1.y]=k2; } cout<<"draw"<<endl; return 0; }
1385:团伙(group)
#include<bits/stdc++.h> using namespace std; int n,m; int p[15000]; int vis[15000]; int findth(int x) { if(x==p[x]) return x; return p[x]=findth(p[x]); } void unionn(int x,int y) { int xx=findth(x); int yy=findth(y); if(xx!=yy) p[yy]=xx; } int main() { scanf("%d %d",&n,&m); for(int i=1;i<=2*n;i++) p[i]=i; for(int i=1;i<=m;i++) { int a,b,c; scanf("%d %d %d",&a,&b,&c); if(a==0) unionn(b,c); if(a==1) { unionn(b+n,c); unionn(b,c+n); } } int cnt=0; for(int i=1;i<=n;i++) { int t=findth(i); if(!vis[t]) { vis[t]=1; cnt++; } } printf("%d\n",cnt); return 0; }
1386:打击犯罪(black)
#include<cstdio> #include<cstring> #include<iostream> #define max(a,b) (a)>(b)?(a):(b) #define min(a,b) (a)<(b)?(a):(b) using namespace std; int n,xx,yy,k,a[1005][1005],dad[1005],b[1005]; int find(int dep){return dad[dep]==dep?dep:dad[dep]=find(dad[dep]);}//并查集 void lj(int x,int y) { xx=find(x); yy=find(y); dad[min(xx,yy)]=max(xx,yy);//连接两个点 } int main() { scanf("%d",&n); for (int i=1;i<=n;++i) { scanf("%d",&a[i][0]); for (int j=1;j<=a[i][0];++j) scanf("%d",&a[i][j]); } for (int i=1;i<=n;++i) dad[i]=i; int i=n+1; while (!k) { i--; for (int j=1;j<=a[i][0];++j) if (a[i][j]>=i) lj(i,a[i][j]);//插入点 memset(b,0,sizeof(b)); for (int j=i;j<=n;++j) b[find(j)]++;//累加 for (int j=i;j<=n;++j) { if (b[j]>n/2)//判断 { k=1;//不符合 break; } } } printf("%d",i); }
1387:搭配购买(buy)
//1387:搭配购买(buy) #include<cstdio> #include<iostream> using namespace std; const int maxn = 10000+10; int p[maxn],sumw[maxn],sumc[maxn]; // 分别记录每件云朵的祖先,每一种搭配的总金额,每一种搭配的总价值 int w[maxn],c[maxn],f[maxn]; //分别记录每一个背包的总金额,总价值,可获得的总的最大价值 int n,m,C; int find(int x)//采用压缩路径法找祖先 { return x==p[x]?x:p[x]=find(p[x]); } int main() { scanf("%d%d%d",&n,&m,&C); for(int i=1;i<=n;i++) scanf("%d%d",&sumw[i],&sumc[i]),p[i]=i; //并查集思路找代表元(祖先) int u,v; for(int i=0;i<m;i++) { scanf("%d%d",&u,&v); int x=find(u),y=find(v); if(x!=y) { p[x]=y; sumw[y]+=sumw[x]; sumc[y]+=sumc[x]; } } //把所有祖先做成背包(每个祖先代表一个搭配集合) int cnt=0; for(int i=1;i<=n;i++) if(p[i]==i){ ++cnt; w[cnt]=sumw[i]; c[cnt]=sumc[i]; } //0-1背包求最大值 for(int i=1;i<=cnt;i++) for(int j=C;j>=w[i];j--) f[j]=max(f[j],f[j-w[i]]+c[i]); printf("%d\n",f[C]); return 0; }
1388:家谱(gen)
//1388:家谱(gen) #include<iostream> using namespace std; string xm1[27][50001],xm[50001]; int num[27],xmn[27][5001],fa[50001],tot,root; int find(string s) { int f=0,sz=s[0]-'A'+1; for(int i=1;i<=num[sz];i++) { if(xm1[sz][i]==s) { f=xmn[sz][i]; break; } } return f; } int zx(int x) { while(fa[x]!=x) { x=fa[x]; } return fa[x]; } void add(string s) { int sz=s[0]-'A'+1; xm[++tot]=s; xm1[sz][++num[sz]]=s; xmn[sz][num[sz]]=tot; fa[tot]=tot; } int main() { string s,txm; int sz,f; char ch; while(cin>>s&&s!="$") { ch=s[0],txm=s.substr(1,s.length() -1); if(ch=='?') cout<<txm<<' '<<xm[zx(find(txm))]<<endl; else { sz=find(txm); if(sz==0) { add(txm); sz=tot; } if(ch=='#')root=zx(sz); else fa[sz]=root; } } // for(int i=1;i<=tot;i++) // cout<<i<<xm[i]<<' '; // cout<<endl; // for(int i=1;i<=tot;i++) // cout<<i<<xm[fa[i]]<<' '; // cout<<endl; // for(int i=1;i<=26;i++) // for(int j=1;j<=num[i];j++) // cout<<j<<xm1[i][j]<<' '; return 0; }
1389:亲戚
#include<cstdio> #include<cstring> const int N=1e5+1; int fa[N],n,m,num[N]; int find(int x) { if(x==fa[x])return x;; return fa[x]=find(fa[x]); } int main() { char ch[2]; int a,b,zx,zy; scanf("%d %d",&n,&m); for(int i=1;i<=n;i++)fa[i]=i,num[i]=1; for(int i=1;i<=m;i++) { scanf("%s %d",ch,&a); zx=find(a); if(ch[0]=='M') { scanf("%d",&b); zy=find(b); if(zy!=zx)fa[zy]=zx,num[zx]+=num[zy]; } else printf("%d\n",num[zx]); } return 0; }
1390:食物链【NOI2001】
#include <cstdio> inline int read() { char c = getchar(); int n = 0; while (c < '0' || c > '9') { c = getchar(); } while (c >= '0' && c <= '9') { n = (n << 1) + (n << 3) + (c & 15); c = getchar(); } return n; } const int maxN = 100005; int n, m, ans, fa[maxN * 3]; int find(int u) { return fa[u] == u ? u : fa[u] = find(fa[u]); } int main() { n = read(), m = read(); for (int i = 1; i <= n * 3; i++) { fa[i] = i; } for (; m; m--) { int opt = read(), u = read(), v = read(); if (u > n || v > n) { ans++; continue; } if (opt == 1) { if (find(u + n) == find(v) || find(u) == find(v + n)) { ans++; } else { fa[find(u)] = find(v); fa[find(u + n)] = find(v + n); fa[find(u + n + n)] = find(v + n + n); } } else { if (find(u) == find(v) || find(u) == find(v + n)) { ans++; } else { fa[find(u + n)] = find(v); fa[find(u + n + n)] = find(v + n); fa[find(u)] = find(v + n + n); } } } printf("%d\n", ans); return 0; }
第五节 最小生成树
1348:【例4-9】城市公交网建设问题
//1348:【例4-9】城市公交网建设问题 #include<iostream> using namespace std; int const N=101; int const inf=1e9; int fa[N],n,m,hp,cnt,rd[N][N],dd[N][N]; struct link{ int x,y,s; }b[N*N],heap[N*N]; void jh(int &x,int &y) { int t=y; y=x; x=t; return; } void put(link x) { heap[++hp]=x; int now=hp,next; link a,b; while(now>1) { next=now/2; a=heap[now],b=heap[next]; if(a.s>b.s)break; heap[now]=b,heap[next]=a; now=next; } } link get() { link x=heap[1]; heap[1]=heap[hp--]; int now=1,next; link a,b; while(now*2<=hp) { next=now*2; a=heap[now]; if(next<hp&&heap[next+1].s<heap[next].s)next++; b=heap[next]; if(a.s<b.s)break; heap[now]=b,heap[next]=a; now=next; } return x; } int find(int x) { if(fa[x]!=x)fa[x]=find(fa[x]); return fa[x]; } int main() { ios::sync_with_stdio(0); link t; cin>>n>>m; for(int i=1;i<n;i++) { fa[i]=i; for(int j=i+1;j<=n;j++) dd[i][j]=inf; } for(int i=1;i<=m;i++) { int x,y,s; cin>>x>>y>>s; if(x>y)jh(x,y); if(dd[x][y]>s) dd[x][y]=s; } cnt=0; for(int i=1;i<n;i++) for(int j=i+1;j<=n;j++) if(dd[i][j]!=inf) { b[++cnt].x=i; b[cnt].y=j; b[cnt].s=dd[i][j]; put(b[cnt]); } cnt=1; while(cnt<n&&hp) { t=get(); int t1=find(t.x),t2=find(t.y); if(t1!=t2) { fa[t2]=t1; rd[t.x][t.y]=1; cnt++; } } cnt=1; for(int i=1;i<n;i++) for(int j=i+1;j<=n;j++) if(rd[i][j])cout<<i<<" "<<j<<endl; return 0; }
1349:【例4-10】最优布线问题
//1349:【例4-10】最优布线问题 #include<iostream> #include<queue> using namespace std; int const N=101; struct link{ int x,y,s; bool operator < (const link t)const {return t.s<s;} }f[N*N]; int fa[N],n,cnt,ans; priority_queue<link>heap; int find(int x) { if(fa[x]!=x)fa[x]=find(fa[x]); return fa[x]; } int main() { ios::sync_with_stdio(0); int tx,ty; link t; cin>>n; for(int i=1;i<=n;i++)fa[i]=i; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { cin>>tx; if(j>i) { f[++cnt].x=i; f[cnt].y=j; f[cnt].s=tx; heap.push(f[cnt]); } } // while(heap.size()) // { // link t=heap.top(); // cout<<t.x<<' '<<t.y<<' '<<t.s<<endl; // heap.pop(); // } cnt=1; while(cnt<n) { t=heap.top(); tx=t.x,ty=t.y; tx=find(tx),ty=find(ty); if(tx!=ty) { fa[ty]=tx; ans+=t.s; cnt++; } heap.pop(); } cout<<ans; return 0; }
1350:【例4-11】最短网络(agrinet)
//1350:【例4-11】最短网络(agrinet) #include<iostream> #include<queue> using namespace std; int const N=101; struct link{ int x,y,s; bool operator < (const link t)const {return t.s<s;} }f[N*N]; int fa[N],n,cnt,ans; priority_queue<link>heap; int find(int x) { if(fa[x]!=x)fa[x]=find(fa[x]); return fa[x]; } int main() { ios::sync_with_stdio(0); int tx,ty; link t; cin>>n; for(int i=1;i<=n;i++)fa[i]=i; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { cin>>tx; if(j>i) { f[++cnt].x=i; f[cnt].y=j; f[cnt].s=tx; heap.push(f[cnt]); } } // while(heap.size()) // { // link t=heap.top(); // cout<<t.x<<' '<<t.y<<' '<<t.s<<endl; // heap.pop(); // } cnt=1; while(cnt<n) { t=heap.top(); tx=t.x,ty=t.y; tx=find(tx),ty=find(ty); if(tx!=ty) { fa[ty]=tx; ans+=t.s; cnt++; } heap.pop(); } cout<<ans; return 0; }
1351:【例4-12】家谱树
//1351:【例4-12】家谱树 #include<iostream> using namespace std; int m[101],n,tx; bool f[101][101]; int main() { ios::sync_with_stdio(0); cin>>n; for(int i=1;i<=n;i++) { cin>>tx; m[i]=i; while(tx) { f[i][tx]=true; cin>>tx; } } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i!=j&&j!=k&&i!=k) f[i][j]=f[i][j]||f[i][k]&&f[k][j]; for(int i=n;i>=1;i--) for(int j=1;j<i;j++) if(f[m[i]][m[j]])swap(m[j],m[i]); for(int i=1;i<n;i++)cout<<m[i]<<' '; cout<<m[n]<<endl; return 0; }
1391:局域网(net)
//1391:局域网(net) #include<iostream> #include<queue> using namespace std; int const N=101; struct link{ int x,y,s; bool operator < (const link t)const {return t.s<s;} }f[N*N]; int fa[N],n,m,cnt,ans,sum; priority_queue<link>heap; int find(int x) { if(fa[x]!=x)fa[x]=find(fa[x]); return fa[x]; } int main() { ios::sync_with_stdio(0); int tx,ty,tz; link t; cin>>n>>m; for(int i=1;i<=n;i++)fa[i]=i; for(int i=1;i<=m;i++) { cin>>tx>>ty>>tz; sum+=tz; f[i].x=tx; f[i].y=ty; f[i].s=tz; heap.push(f[i]); } cnt=1; while(cnt<n) { t=heap.top(); tx=t.x,ty=t.y; tx=find(tx),ty=find(ty); if(tx!=ty) { fa[ty]=tx; ans+=t.s; cnt++; } heap.pop(); } cout<<sum-ans<<endl; return 0; }
1392:繁忙的都市(city)
//1392:繁忙的都市(city) #include<iostream> #include<queue> using namespace std; int const N=301; struct link{ int x,y,s; bool operator < (const link t)const {return t.s<s;} }f[N*N]; int fa[N],n,m,cnt,ans; priority_queue<link>heap; int find(int x) { if(fa[x]!=x)fa[x]=find(fa[x]); return fa[x]; } int main() { ios::sync_with_stdio(0); int tx,ty,tz; link t; cin>>n>>m; for(int i=1;i<=n;i++)fa[i]=i; for(int i=1;i<=m;i++) { cin>>tx>>ty>>tz; f[i].x=tx; f[i].y=ty; f[i].s=tz; heap.push(f[i]); } cnt=1; while(cnt<n) { t=heap.top(); tx=t.x,ty=t.y; tx=find(tx),ty=find(ty); if(tx!=ty) { fa[ty]=tx; ans=t.s; cnt++; } heap.pop(); } cout<<n-1<<' '<<ans<<endl; return 0; }
1393:联络员(liaison)
//1393:联络员(liaison) #include<iostream> #include<queue> using namespace std; int const N=2001; struct link{ int x,y,s; bool operator < (const link t)const {return t.s<s;} }f[N*N]; int fa[N],b[N][N],n,m,cnt,ans; priority_queue<link>heap; int find(int x) { if(fa[x]!=x)fa[x]=find(fa[x]); return fa[x]; } int main() { ios::sync_with_stdio(0); int p,tx,ty,tz; link t; cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) b[i][j]=1e9; for(int i=1;i<=n;i++)fa[i]=i; for(int i=1;i<=m;i++) { cin>>p>>tx>>ty>>tz; if(p==1) { ans+=tz; tx=find(tx); ty=find(ty); if(tx!=ty)fa[ty]=tx; } else { if(b[tx][ty]>tz) b[tx][ty]=tz; } } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(b[i][j]<1e9) { f[++cnt].x=i; f[cnt].y=j; f[cnt].s=b[i][j]; heap.push(f[cnt]); } while(!heap.empty()) { t=heap.top(); tx=t.x,ty=t.y; tx=find(tx),ty=find(ty); if(tx!=ty) { fa[ty]=tx; ans+=t.s; cnt++; } heap.pop(); } cout<<ans<<endl; return 0; }
1394:连接格点(grid)
//1394:连接格点(grid) #include<iostream> using namespace std; const int N=1e6+1; int n,m,fa[N],num[N],sum,row[1000],ans; int find(int x) { if(fa[x]!=x)fa[x]=find(fa[x]); return fa[x]; } int main() { ios::sync_with_stdio(0); cin>>m>>n; int x1,y1,x2,y2,a,b; for(int i=1;i<=n*m;i++)num[i]=1,fa[i]=i; while(cin>>x1) { cin>>y1>>x2>>y2; a=x1*n+y1-n; b=x2*n+y2-n; a=find(a),b=find(b); if(a!=b) { fa[b]=a,num[a]+=num[b]; if(y1!=y2) if(y1<y2)row[y1]=1; else row[y2]=1; } } for(int i=1;i<n;i++)sum+=row[i]; ans=(m+1)*n-2-sum; for(int i=1;i<=n*m;i++) { a=find(i); if(a==i&&num[a]!=1)ans-=num[a]-1; } cout<<ans<<endl; return 0; }
第六节 拓扑排序与关键路径
1352:【例4-13】奖金
//1352:【例4-13】奖金 #include<iostream> #include<queue> using namespace std; struct link{ int pre,to; }f[20001]; int n,m,last[10001],q[10001],num[10001],cnt,rd=0,money,k; int main() { ios::sync_with_stdio(0); int x,y; cin>>n>>m; for(int i=1;i<=m;i++) { cin>>x>>y; num[x]++; f[i].pre=last[y]; f[i].to=x; last[y]=i; } while(cnt<n) { rd=0; for(int i=1;i<=n;i++) if(num[i]==0) { rd++,cnt++,num[i]=1e9; q[rd]=i,money+=100; } if(rd==0)break; money+=k*rd; k++; for(int j=1;j<=rd;j++) for(int i=last[q[j]];i;i=f[i].pre)num[f[i].to]--; } if(cnt==n)cout<<money<<endl; else cout<<"Poor Xed\n"; return 0; }
1395:烦人的幻灯片(slides)
//1395:烦人的幻灯片(slides) #include<iostream> using namespace std; int n,msg[27][27],num[27],zm[27][5],ans[27],cnt; int main() { ios::sync_with_stdio(0); int x,y; cin>>n; for(int i=1;i<=n;i++) for(int j=1;j<=4;j++) cin>>zm[i][j]; for(int i=1;i<=n;i++) { cin>>x>>y; for(int k=1;k<=n;k++) if(zm[k][1]<=x&&x<=zm[k][2]&&zm[k][3]<=y&&y<=zm[k][4]) msg[k][i]=1,num[k]++; } // for(int i=1;i<=n;i++) // { // cout<<num[i]<<':'; // for(int j=1;j<=n;j++) // cout<<msg[i][j]<<' '; // cout<<endl; // } while(1) { cnt=0; for(int i=1;i<=n;i++) if(num[i]==1) { cnt++; num[i]=-1; for(int j=1;j<=n;j++) if(msg[i][j]) { ans[cnt]=j; break; } } if(cnt==0)break; for(int i=1;i<=cnt;i++) { x=ans[i]; for(int j=1;j<=n;j++) if(num[j]>0&&msg[j][x]) msg[j][x]=0,num[j]--; } } for(int i=1;i<=n;i++) if(num[i]!=-1) { cout<<"None\n"; return 0; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(msg[i][j]) { cout<<char(i-1+'A')<<' '<<j<<endl; break; } return 0; }
1396:病毒(virus)
//1396:病毒(virus) #include<iostream> using namespace std; int const N=5e4+1; int n,k; string s[N],ss,sans; bool gz[26][26],p[26];//gz[x][y]表示第x个字母的原字母比第y个字母的原字母靠后 int f[27],cnt,num[27],ans,key[27]; int main() { ios::sync_with_stdio(0); for(int i=0;i<27;i++)key[i]=-32; int x,y; cin>>k; for(int i=1;i<=k;i++) { cin>>s[i]; for(int j=0;j<s[i].length() ;j++) p[s[i][j]-'a']=true;//收集用到哪些字母 } cin>>ss; for(int i=1;i<k;i++) { for(int j=0;j<s[i].length() &&j<s[i+1].length();j++) { x=s[i][j]-'a',y=s[i+1][j]-'a'; if(x!=y){gz[y][x]=true;break;}//前面字母相同看下一个字母 ,否则不用看后面字母 //后排字母应该比前排字母靠后,以此建立排序规则 } } for(int i=0;i<26;i++)//把所用到字母建立一个1-n的映射 if(p[i])f[++cnt]=i; n=cnt; //根据规则建立有向图,并统计有向图入度 for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i!=j&&gz[f[i]][f[j]])num[f[i]]++; cnt=0; while(cnt<n) { k=0; for(int i=1;i<=n;i++) { if(num[f[i]]==0)//入度为0说明对应字母应排前面,第x个入度为0的字母应是用到的第x个字母 { k++; ans=f[i]; num[f[i]]=-1; } } if(k!=1)//字典无错必只有一个入度为0点 { cout<<0<<endl; return 0; } for(int i=1;i<=n;i++)//去掉己确认点的所有关联及入度统计量 if(gz[f[i]][ans])gz[f[i]][ans]=false,num[f[i]]--; key[ans]=f[++cnt];//确认对应关系 } for(int i=0;i<ss.length() ;i++) { k=key[ss[i]-'a']; if(k<0)//字典不全 { cout<<0<<endl; return 0; } sans+=char(k+'a'); } cout<<sans; return 0; }
点击查看AC代码