《算法笔记》 第三章3.1节学习笔记

《算法笔记》 第三章学习笔记

编译环境: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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值