《算法笔记》 第三章学习笔记
编译环境:codeblocks20.03
备注:本文留作作者自用,如有错误敬请指出
3.1节
【PAT B1001】
#include<cstdio>//耗时5ms,用iostream耗时22ms
int main()
{
int n;
int cnt=0;
scanf("%d",&n);
while(n!=1)
{
if(n%2==0)
n=n/2;
else
n=(3*n+1)/2;
cnt++;
}
printf("%d",cnt);
return 0;
}
【pat B1032】
#include<cstdio>//自己没写出来,借鉴了书上的程序
#define maxn 100001//这里要大于10^5
int main()
{
int n;
int schID;
scanf("%d",&n);
int school[maxn]={0};
for(int score=0,cnt=0;cnt<n;cnt++)
{
scanf("%d%d",&schID,&score);
school[schID]+=score;
}
int k=-1,max=-1;
for(int i=1;i<=n;i++)
if(max<school[i])
{
max=school[i];
k=i;
}
printf("%d %d\n",k,max);
return 0;
}
【PAT B1011】
#include<cstdio>//耗时3ms
int main()
{
int n;
scanf("%d",&n);
int judge[10]={0};//比书上的麻烦一点,可以但没必要
for(int i=0;i<n;++i)
{ long long a,b,c;//整数A,B,C在[-2^32,2^32]之间,定义在for循环里面好像更节省时间
scanf("%lld%lld%lld",&a,&b,&c);
if((a+b)>c)
judge[i]=1;
}
for(int i=0;i<n;++i)
if(judge[i]==1)
printf("Case #%d: true\n",i+1);
else
printf("Case #%d: false\n",i+1);
return 0;
}
题目说结尾无空行,但是好像不影响评测结果
【PAT B1016】
#include<cstdio>//耗时3ms,感觉写得有点啰嗦
int fact(int n)
{ int m=1;
for(;n>0;n--)
m*=10;
return m;
};
int main()
{
long long a,b;
int da,db,n1=0,n2=0;
scanf("%lld%d%lld%d",&a,&da,&b,&db);
for(;(a/10)!=0;a=a/10)
if(a%10==da)
n1++;
if(a==da)//还要考虑a首位数字是PA的情况,b同理
n1++;
for(;(b/10)!=0;b=b/10)
if(b%10==db)
n2++;
if(b==db)
n2++;
for(a=0;n1>0;--n1)//这里直接把a和b当成pa和pb了,废物利用
a+=da*fact(n1-1);
for(b=0;n2>0;--n2)
b+=db*fact(n2-1);
printf("%lld",a+b);
return 0;
}
【PAT B1026】
#include<cstdio>//耗时4ms
int main()
{
int c1,c2,time;//int范围够用
scanf("%d%d",&c1,&c2);
if((c2-c1)%100>=50) time=(c2-c1)/100+1;
else time=(c2-c1)/100;
//输出不足两位时高位用0补充
printf("%02d:%02d:%02d",time/3600,time%3600/60,time%60);
return 0;
}
【PAT B1046】
#include<cstdio>//耗时5ms
int main()
{
int n,fail_1=0,fail_2=0,s1,s2,sum,h1,h2;
scanf("%d",&n);
while(n--)
{
scanf("%d%d%d%d",&s1,&h1,&s2,&h2);
sum=s1+s2;
if(h1==sum && h2!=sum)
fail_2++;
else if(h2==sum && h1!=sum)
fail_1++;
}
printf("%d %d",fail_1,fail_2);
return 0;
}
【PAT B1008】
#include<cstdio>//不会写,抄书的,耗时4ms
int main()
{
int m,n,cnt=0;//cnt记录已输出数的个数
scanf("%d %d",&n,&m);
m=m%n;//m不一定小于n
int ar[100];
for(int i=0;i<n;++i)
scanf("%d",&ar[i]);
for(int i=n-m;i<n;++i)
{ printf("%d",ar[i]);
cnt++;
if(cnt<n) printf(" ");}
for(int i=0;i<n-m;++i)
{ printf("%d",ar[i]);
cnt++;
if(cnt<n) printf(" ");}
return 0;
}
【PAT B1012】
#include<cstdio>//改了无数次才答案正确,麻了
int main()
{
int n,a1,a2,a3,a5,rr4;
int r1,r2,r3,r4,r5;//判断某类数字是否存在的标志
a1=a2=a3=a5=r1=r2=r3=r4=rr4=r5=0;//把它们全部设为0
int rr2=-1;//用于交错求和的符号变换
double a4=0;//输出要保留一位小数所以设为浮点数
int ar[1000];//用于存放N个正整数
int max=-1;
scanf("%d",&n);
for(int i=0;i<n;++i)
{
scanf("%d",&ar[i]);
if(ar[i]%5==0 && ar[i]%2==0){
r1=1;
a1+=ar[i];
}if(ar[i]%5==1){
a2-=rr2*ar[i];
rr2=-rr2;
r2=1;
}if(ar[i]%5==2){
a3++;
r3=1;
}if(ar[i]%5==3){
a4+=ar[i];
rr4++;
r4=1;
}if(ar[i]%5==4){
r5=1;
if(max<ar[i]) max=ar[i];
}
}
if(r1) printf("%d ",a1);else printf("N ");
if(r2) printf("%d ",a2);else printf("N ");
if(r3) printf("%d ",a3);else printf("N ");
if(r4) printf("%.1f ",a4/rr4);else printf("N ");
if(r5) printf("%d",max);else printf("N");
return 0;
}
【PAT B1018】
#include<cstdio>//完全是列举出来的,耗时11ms
int main()
{
int n,win1,win2,fail1,fail2;//分别记录甲乙输赢次数
int c1,c2,j1,j2,b1,b2;//分别记录甲乙用哪个手势获胜的次数
char gest1,gest2;//存放甲乙手势
win1=win2=fail1=fail2=c1=c2=j1=j2=b1=b2=0;
scanf("%d",&n);
getchar();//吸收换行符
for(int i=0;i<n;++i){
scanf("%c %c",&gest1,&gest2);
getchar();//同上
if(gest1=='C')//列举了九种情况
{if(gest2=='C');
else if(gest2=='J') {win1++;fail2++;c1++;}
else {win2++;fail1++;b2++;}}
else if(gest1=='B')
{if(gest2=='C') {win1++;fail2++;b1++;}
else if(gest2=='J') {win2++;fail1++;j2++;}
else ;}
else
{if(gest2=='C') {win2++;fail1++;c2++;}
else if(gest2=='J');
else {win1++;fail2++;j1++;}}
}
if(j1>b1&&j1>c1) gest1='J';//甲根据题目输出J的情况
else if(c1>b1&&c1>=j1) gest1='C';//甲输出C的情况
else gest1='B';//剩下的情况全输出B
if(j2>b2&&j2>c2) gest2='J';//乙也一样
else if(c2>b2&&c2>=j2) gest2='C';
else gest2='B';
printf("%d %d %d\n",win1,n-win1-fail1,fail1);//顺序是胜平负
printf("%d %d %d\n",win2,n-win2-fail2,fail2);
printf("%c %c",gest1,gest2);
return 0;
}
【PAT A1042】
#include<cstdio>//不会写,抄书的,耗时3ms
int main()
{
char a[]={'S','H','C','D','J'};
const int N=54;
int start[N+1],end[N+1],next[N+1];
int n;
scanf("%d",&n);
for(int i=1;i<=N;++i)
start[i]=i;
for(int i=1;i<=N;++i)
scanf("%d",&next[i]);
for(int i=0;i<n;++i){//执行n次操作
for(int j=1;j<=N;++j)
end[next[j]]=start[j];
for(int j=1;j<=N;++j)
start[j]=end[j];
}
for(int i=1;i<=N;++i){
start[i]--;
printf("%c%d",a[start[i]/13],start[i]%13+1);
if(i!=N)
printf(" ");
}
return 0;
}
【PAT A1046】
#include<cstdio>//自己写的运行超时了,我谔谔
int main()
{
int n,m,begin_,end_,temp,order=0,sum=0;
int a[100001];
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%d",&a[i]);
sum+=a[i];
}
scanf("%d",&m);
for(int i=0;i<m;++i){
scanf("%d%d",&begin_,&end_);
if(begin_>end_){
temp=begin_;
begin_=end_;
end_=temp;
}
order=0;
int p=end_-begin_;
int q=begin_;
for(int j=0;j<p;++j){
order+=a[q-1];
q++;
}
if(order<sum-order) printf("%d",order);
else printf("%d",sum-order);
if(i<m-1) printf("\n");
}
return 0;
}
#include<cstdio>//按照书上的改正后的,时间复杂度为O(1)
int main()
{
int n,m,begin_,end_,temp,sum=0;
int a[100001];//这里要大于10的5次方
int dis[100001];
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%d",&a[i]);
sum+=a[i];
dis[i]=sum;
}
scanf("%d",&m);
for(int i=0;i<m;++i){
scanf("%d%d",&begin_,&end_);
if(begin_>end_){
temp=begin_;
begin_=end_;
end_=temp;
}
int p=dis[end_-2]-dis[begin_-2];
if(p<sum-p) printf("%d",p);
else printf("%d",sum-p);
if(i<m-1) printf("\n");
}
return 0;
}
【PAT A1065】
#include<cstdio>
int main()
{
int n;
scanf("%d",&n);
int d=n;
while(n--){
long long a,b,c;
scanf("%lld%lld%lld",&a,&b,&c);
long long sum=a+b;
//这里正溢出和负溢出的判断必须在前面,否则会出现错误
if(a>0 && b>0 && sum<0) printf("Case #%d: true",d-n);
else if(a<0 && b<0 && sum>=0) printf("Case #%d: false",d-n);
else if(sum>c) printf("Case #%d: true",d-n);
else printf("Case #%d: false",d-n);
printf("\n");
}
【PAT B1010】
#include<cstdio>//终于通过了TAT
#include<vector>
using std::vector;
int main()
{
vector<int> a={},b={};//a存放多项式非零项系数,b存放多项式非零项指数
int i,c,j=0,flag=0;//flag用来标识零多项式,书上题目不完整坑死我了
while(scanf("%d%d",&i,&c)!=EOF){
j++;
a.push_back(i);
b.push_back(c);
if(b[j-1]) flag=1;//说明存在不为0的多项式指数
}
if(flag==0) printf("0 0");
else {
for(int k=0;k<j;k++){
int d=b[k];
b[k]--;//求导后的指数
if(k==j-1) printf("%d %d",a[k]*d,b[k]);//当到达导数多项式结尾处
else if(b[k+1]>0) printf("%d %d ",a[k]*d,b[k]);//当多项式下一项不为常数项
else {printf("%d %d",a[k]*d,b[k]);//当多项式下一项为常数项
break;}//结束循环了捏
}
}
return 0;
}
【PATA1002】
#include<cstdio>//还有一个格式错误但我实在是找不到了
#include<cmath>//要用到fabs()函数
int main()
{
double a[1010]={0};//数组用于存放相同指数项的系数之和
double d;
int c,max=-1,sum=0;//max存放最大指数,sum存放非零项个数
int flag[1010]={0};//存放输入过某个指数项的标记
for(int i=0;i<2;i++){
int j;
scanf("%d",&j);
for(int k=0;k<j;k++){
scanf("%d%lf",&c,&d);
flag[c]=1;
if(c>max) max=c;
a[c]+=d;
}
}
for(int m=0;m<=max;m++)
if(flag[m]&&fabs(a[m])>1e-8) sum++;
printf("%d ",sum);
for(int i=max;i>=0;i--){
if(flag[i]==0||fabs(a[i])<1e-8) continue;
printf("%d %.1f",i,a[i]);
sum--;
if(sum)
printf(" ");
}
return 0;
}
【PAT A1009】
#include<cstdio>//不理解为什么用结构体就对了
struct poly{
int exp;
double cof;
}a[1001];
double b[2001];
int main()
{
double d;
int c,sum=0;
int j,n;
scanf("%d",&j);
for(int k=0;k<j;k++){
scanf("%d %lf",&a[k].exp,&a[k].cof);
}
scanf("%d",&n);
for(int k=0;k<n;k++){
scanf("%d %lf",&c,&d);
for(int p=0;p<j;p++){
b[c+a[p].exp]+=(a[p].cof*d);
}
}
for(int i=0;i<=2000;i++){
if(b[i]!=0.0) {
sum++;}
}
printf("%d",sum);
for(int i=2000;i>=0;i--){
if(b[i]!=0.0){
printf(" %d %.1f",i,b[i]);
}
}
return 0;
}