【睛神PAT】3.1简单模拟

3.1 简单模拟

1、[PAT B1001]害死人不偿命的(3n+1)猜想

  • 1、注意初始化输入变量
#include <stdio.h>
int main(){
    int a;
    scanf("%d",&a);
    int step=0;
    while(a!=1){
    if(a%2==0)
        a/=2;
    else
        a=(3*a+1)/2;
        step++;
    }
    printf("%d",step);
}

2、 [PAT B1032]挖掘机技术哪家强

#include<stdio.h>
#include<stdlib.h>
int main(){
    int T;
    scanf("%d",&T);				//输出对应T大小
    int *b=(int*)malloc(sizeof(int)*T);
    int MAX=-1;					//最大值
    int MAX_i=-1;				//最大值坐标
    while(T--){					//明显输入T次的输出
        int index,value;
        scanf("%d %d",&index,&value);
        //对应值输入保存在对应的数组中
        *(b+index-1)+=value;
        //如果当前值是最大值
        if(*(b+index-1)>MAX){
            MAX=*(b+index-1);
            MAX_i=index-1;
        }
    }
    printf("%d %d",MAX_i+1,*(b+MAX_i));
}

3、[PAT B1011]A+B和C

  • 2、注意输入变量表示范围 int表示为[-231,231-1]
  • 题目给出的值范围为:[-231,231]会超出对应值,而且两个值相加也会超过对应值,所以这里改为long long型
#include<stdio.h>
#include<stdlib.h>
int main(){
    int T;
    scanf("%d",&T);
    int i=1;
    while(T--){
        long long int a,b,c;
        int flag=0;
        scanf("%lld %lld %lld",&a,&b,&c);
        if(a+b>c)
        flag=1;
        if(flag==0)
        printf("Case #%d: false\n",i);
        else
        printf("Case #%d: true\n",i);
        i++;
        }
}

4、[PAT B1016]部分A+B

  • 3、对应还是是否超出对应范围 1010是要大于对应的231的,所以用long long表示,其次对应的判断每位是要采用A!=0,而非A/10!=0判断
#include<stdio.h>
int main(){
    long long A,B;		//定义时额外注意是否超出对应范围
    int Da,Db;
    scanf("%lld %d %lld %d",&A,&Da,&B,&Db);
    int counta=0;
    int countb=0;
    long long newa=0;
    long long newb=0;
    int k;
    while(A!=0){		//循环判断A注意直接判断对应是否为0
        k=A%10;
        A=A/10;
        if(k==Da)counta++;
    }
    while(B!=0){		//循环判断B注意直接判断对应是否为0
        k=B%10;
        B=B/10;
        if(k==Db)countb++;
    }
    while(counta--){
        newa=newa*10+Da;
    }
    while(countb--){
        newb=newb*10+Db;
    }
    printf("%lld",newa+newb);
    return 0;			//要有对应的返回值
}

5、[PAT B1026]程序运行时间

  • 4、注意对应时间表示要求是两位,所以对应每一位在显示的时候要用02d的方式补0和对应两位显示即可
#include<stdio.h>
#include<time.h>
#define CLK_TCK 100;
int main(){
    int start,end;
    int hh=0,mm=0,ss=0;
    scanf("%d %d",&start,&end);                 //输入开始和结束时间
    float total=(end-start)*1.0/CLK_TCK;        //最后运行总时间
    hh=total/3600;                              //时
    total-=hh*3600;                             
    mm=total/60;                                //分
    total-=mm*60;
    ss=total;                                   //秒
    if(total-ss>0.4)ss+=1;                      //秒进位
    //不足位补0
    if(hh==0)printf("00:");else printf("%02d:",hh);
    if(mm==0)printf("00:");else printf("%02d:",mm);
    if(ss==0)printf("00");else printf("%02d",ss);
    return 0;
}

6、[PAT B1046]划拳

  • 5、注意还原初始化对应值
#include<stdio.h>
int main (){
    int T;                      //次数
    int Ah,Ae,Bh,Be;            //A喊,A划,B喊,B划
    int flaga=0,flagb=0;        //A和B是否要喝酒
    int counta=0,countb=0;      //A和B喝酒次数
    scanf("%d",&T);             
    while(T--){
        scanf("%d %d %d %d",&Ah,&Ae,&Bh,&Be);
        if((Ah+Bh)==Ae)
        flaga=1;
        if((Ah+Bh)==Be)
        flagb=1;
        if(flaga>flagb){
            countb++;
        }
        if(flaga<flagb){
            counta++;
        }
    flaga=flagb=0;				//记得要归0处理全部
    }
    printf("%d %d",counta,countb);
    return 0;
}

7、[PAT B1008]数组元素循环右移问题

方法一:借助另外数组完成具体操作

  • 注意初始化对应值的变化
#include<stdio.h>
#include<stdlib.h>
int main(){
    int N,M;
    scanf("%d %d",&N,&M);
    int*a=(int *)malloc(sizeof(int)*N);
    int*b=(int *)malloc(sizeof(int)*N);
    int i=0;
    int N2=N;
    int N3=N;
    int step=0;
    //循环输入值
    while(N--){
        scanf("%d",a+i);
        *(b+i)=*(a+i);
        i++;
    }
    i=0;
    //循环移动
    while(N2--){
        step=(i+M)%N3;
        *(a+step)=*(b+i);
        i++;
    }
    //对应输出值
    for(int i=0;i<N3;i++){
        printf("%d",*(a+i));
        if(i!=N3-1)
        printf(" ");
    }
    return 0;
}

方法二:直接完成对应输出

  • 对应修证m,防止m过大
  • 要考虑特殊的情况保证不能输出太大,所以要保证对应的空格输出
  • 逆向思维将后边的先搬到前面进行输出,即n-m—>n,然后再输出0—>n-m内容
#include<stdio.h>
int main(){
	int a[110];
	int n,m,count=0;//count记录对应数的个数
	m=m%n;//防止m过大修证m
	forint i=n-m;i<n;i++){
	printf("%d",a[i]);
	count++;//已输出数个数+1
	if(count<n)printf(" ");
	}
	for(int i=0;i<n-m;i++){
	printf("%d",a[i]);
	count++;//已输出数个数+1
	if(count<n)printf(" ");
	}
	return 0;
}

8、[PAT A1065]A+B and C(64bit)

-区别于上述的A+B>C在于对应的越界情况考虑,就是很大的值超乎了64位

  • 正越界成负值:比原来的大
  • 负越界成正值或者0:比原来的要小很小
  • 其他情况和上述一样
#include<stdio.h>
#include<stdlib.h>
int main(){
    int T;
    scanf("%d",&T);
    int i=1;
    long long int res;
    while(T--){
        long long int a,b,c;
        int flag=0;
        scanf("%lld %lld %lld",&a,&b,&c);
        res=a+b;
        if(a>0&&b>0&&res<0)flag=1;              //当a>0,且b>0,res<0时其实就是对应着正越界,说明大于c
        else if(a<0&&b<0&&res>=0)flag=0;        //当a<0,且b<0,res>=0时说明就是负越界就是特别小,说明小于c
        else if(res>c)flag=1;                   //未越界,直接比大小
        if(flag==0)
        printf("Case #%d: false\n",i);
        else
        printf("Case #%d: true\n",i);
        i++;
        }
}

9、[PAT B1012]数字分类

  • 要给定对应的个数记录,表征是否有值
  • 初始化值得时候可以引入<string.h>借助memset进行初始化赋值
  • 精度保留一位得时候,之后得位会采用四舍五入得方式进行向前进位
#include <stdio.h>
#include <string.h>
int main(){
    int an[5];
    int count[5];
    memset(an,0,sizeof(an));            //初始化结果集合
    memset(count,0,sizeof(count));      //初始化个数集合
    int T;                              //个数
    scanf("%d",&T);       
    int temp;   
    int flag1=0;                        //交错验证flag           
    while(T--){
        scanf("%d",&temp);
        switch(temp%5){
            //余数为0加偶数
            case 0:
                if(temp%2==0){
                    count[0]++;
                    an[0]+=temp;
                }
            break;
            //余数为1交错加
            case 1:
                count[1]++;
                if(flag1==0){
                    an[1]+=temp;
                    flag1=1;
                }
                else{
                    an[1]-=temp;
                    flag1=0;
                }
            break;
            //余数为2加个数
            case 2:
                count[2]++;
                an[2]++;
            break;
            //余数为3求平均
            case 3:
                count[3]++;
                an[3]+=temp;
            break;
            //余数为4求最大
            case 4:
                count[4]++;
                if(temp>an[4])
                    an[4]=temp;
            break;
        }
    }
    for(int i=0;i<5;i++)
    {
        if(count[i]==0)
            printf("N");
        else if(i!=3)
            printf("%d",an[i]);
        else if(i==3)
            printf("%.1f",an[i]*1.0/count[i]);
        if(i!=4)
            printf(" ");
    }
    return 0;
}

10、[PAT B1018]锤头剪刀布

  • 注意顺序性,其实是由限定对应顺序得,为字母序进行纠正
#include<stdio.h>
#include<string.h>
//according to the index print the correct char
void printchar(int i){
    if(i==0)
    printf("B");
    else if(i==1)
    printf("C");
    else
    printf("J");
}
int main(){
    int T;                              //total_time
    char A,B;                           //A,B option
    int timeA[3];                       //b,c,j——A win
    int timeB[3];                       //b,c,j——B win
    memset(timeA,0,sizeof(timeA));
    memset(timeB,0,sizeof(timeB));
    scanf("%d",&T);
    getchar();
    int total=T;                        //total time all
    //battle
    while(T--){
        scanf("%c %c",&A,&B);
        if(A=='C'&&B=='J')
        timeA[1]++;
        else if(A=='C'&&B=='B')
        timeB[0]++;
        else if(A=='J'&&B=='C')
        timeB[1]++;
        else if(A=='J'&&B=='B')
        timeA[2]++;
        else if(A=='B'&&B=='C')
        timeA[0]++;
        else if(A=='B'&&B=='J')
        timeB[2]++;
        getchar();
    }
    int Awin=timeA[0]+timeA[1]+timeA[2];
    int Bwin=timeB[0]+timeB[1]+timeB[2];
    int pin=total-Awin-Bwin;
    int max_a=0,max_b=0,maxa=0,maxb=0;
	//find maxa and maxb
    for(int i=0;i<3;i++){
        //find max a
        if(timeA[i]>maxa){
        max_a=i;
        maxa=timeA[i];}
        //find max b
        if(timeB[i]>maxb){
        max_b=i;
        maxb=timeB[i];}
    }
    printf("%d %d %d\n",Awin,pin,Bwin);
    printf("%d %d %d\n",Bwin,pin,Awin);
    printchar(max_a);
    printf(" ");
    printchar(max_b);
    return 0;
}

11、[PATB1010]一元多项式求导

  • 误区一:对于那些但项求导为0 0得输出
  • 误区二:关于结尾部分空格的调控安排
  • 在这里要注意的是首先个别情况,如果只有一组不应该输出空格跳出
  • 如果有两组,最后一组是0那么倒数第二组不应该输出空格;最后一组非0,应该输出空格
  • 如果有大于两组,那么两组之前都应该输出空格,有点类似递归的总体思路
#include<stdio.h>
#include<string.h>
int main(){
    int A[10000];
    memset(A,0,sizeof(A));
    int i=0;
    int temp;
    int count=0;
    //循环读入值进行求解
    while(scanf("%d",&temp)!=EOF){
    A[i]=temp;
    i++;
    }
    //进行求导运算
    for(int index=0;index<i;index+=2){
        //如果对应指数为0跳过不求导
        if(*(A+index+1)==0)
        continue;
        //否则其实有非零状态
        else{
            count++;
            *(A+index)*=*(A+index+1);                   //新系数
            *(A+index+1)-=1;                            //新导数
            printf("%d %d",*(A+index),*(A+index+1));    //对应输出值
            	//如果是
                if(index<i-4&&i>4)
                  printf(" ");
                  //倒数两组讨论具体情况
                else if(index==i-4){
                    if(*(A+i-1)==0);
                    else printf(" ");
                }
        }
    }
    //求导之后若是没有任何非0项输出0 0
    if(count==0)
    printf("0 0");
    return 0;
}

12、[PATA1002] A+B for Polynomials

  • 跨行针对PAT是可以直接进行对应输入操作的
  • 注意对应数字存放的具体形式要额外注意是float还是int
  • 可能会抵消成0,在整个的设计中,所以设计时理应额外特别注意这点
#include<stdio.h>
#include<string.h>
int main(){
    float an[1000];
    memset(an,0,sizeof(an));
    int T1,T2;
    int N;
    float aN;
    int Maxindex=0;
    int flag=0;
    scanf("%d",&T1);        //t1 time
    while(T1--){
        scanf("%d %f",&N,&aN);
        if(N>Maxindex)
        Maxindex=N;
        an[N]+=aN;
    }

    scanf("%d",&T2);        //t2 time
    while(T2--){
        scanf("%d %f",&N,&aN);
        if(N>Maxindex)
        Maxindex=N;
        an[N]+=aN;
    }
    int counttotal=Maxindex;
    int count=0;
    //static total count number
    while(counttotal>=0){
        if(an[counttotal]!=0)
        count++;
        counttotal--;
    }
    printf("%d",count);
    //print all number in static
    while(Maxindex>=0){
        if(an[Maxindex]!=0){
        printf(" %d %.1f",Maxindex,an[Maxindex]);
        }
        Maxindex--;
    }
    return 0;
}

13、[PATA1009] Product of Polynomials

  • 该题和上一题最大的区别在于上一题有点类似于应用到了具体桶排序的方式,但是对于乘积而言,这样的话复杂度会非常的高
  • 但是这里的收获也是有的,有些时候其实我们可以借助具体的静态数组完成任务,而不一定非得去刻意追求动态数组的空间尽可能少
  • 结合答案其实是可以用结构体的形式去表示这种对应结构的
  • 在这道题里面有两个难点,①是保证不重复项,这点我用了返回去不断搜索的方式去完成,复杂度确实有点高,但其实还可以;②保证对应是有序的,采用了冒泡排序的方式去排序,冒泡排序的方式其实有一定的复杂度不高,n-1趟第一次变量,然后是每一个都与下一个去比较,进行冒泡排序的过程
  • 针对scanf中数组的输入有点混淆,对于数组而言a+i可直接对应输入,而a[i]要用地址符去表示修正
  • 标准答案的地方好在其实可以在对第二个输入时,边输入边进行对应累加,这样的话一方面保证了不会重复,另一方面顺序是从大到小的一个规律
  • 细节的坑在于最后可能系数为0,要将对应系数为0的项进行对应的删除处理
#include<stdio.h>
int main(){
    int T1,T2;              //time per line
    int index[10][2];       //0 present A; 1 present B
    float value[10][2];
    //standard answers store in these two array
    int standard_index[100];        
    float standard_value[100];
    int sindex=0;
    int count=0;
    int flag=0;
    //input array a
    scanf("%d",&T1);
    for(int i=0;i<T1;i++){
        scanf("%d %f",&index[i][0],&value[i][0]);
    }
    //input array b
    scanf("%d",&T2);
    for(int i=0;i<T2;i++){
        scanf("%d %f",&index[i][1],&value[i][1]);
    }
    int tempN=0;
    float tempaN=0;
    //product
    for(int i=0;i<T1;i++){
        for(int j=0;j<T2;j++){
            flag=0;
            tempN=index[i][0]+index[j][1];
            tempaN=value[i][0]*value[j][1];
            //find same value
            for(int k=0;k<sindex;k++){
                if(tempN==standard_index[k]){
                flag=1;
				standard_value[k]+=tempaN;
                break;
            	}
            }
            //no same value
            if(flag==0){
                standard_index[sindex]=tempN;
                standard_value[sindex]=tempaN;
                sindex++;
        	}
        }
    }
    //bubble sort
    int swap=0;
    for(int i=1;i<sindex;i++){                          //首先进行n-1遍
    	for(int j=0;j<sindex-i;j++){                    //每一趟都是该数与下一个数进行比较
    		if(standard_index[j]<standard_index[j+1]){
    			swap=standard_index[j];
    			standard_index[j]=standard_index[j+1];
    			standard_index[j+1]=swap;
    			swap=standard_value[j];
    			standard_value[j]=standard_value[j+1];
    			standard_value[j+1]=swap;
			} 
		} 
	}
    for(int i=0;i<sindex;i++){
        if(standard_value[i]!=0)
        count++;
    }
    //print the answer
    printf("%d",count);
    for(int i=0;i<sindex;i++){
        if(standard_value[i]!=0)
        printf(" %d %.1f",standard_index[i],standard_value[i]);
    }

}

14、[PATA1042] Shuffling Machine

  • 核心点在交换牌而非顺序,有时候不要想复杂了,只是简单得想对应得牌和顺序即好
  • 打印特定元素规律时可借助对应数组完成相关操作
#include<cstdio>
const int N=54;
char mp[5]={'S','H','C','D','J'};
int start[N+1],end[N+1],next[N+1];
//main function 
int main(){
  int K;
  scanf("%d",&K);
  for(int i=1;i<=N;i++)
  	start[i]=i;
  for(int i=1;i<=N;i++)
	scanf("%d",next+i);
  while(K--){
  for(int i=1;i<=N;i++)
  	end[next[i]]=start[i];
  for(int i=1;i<=N;i++)
  	start[i]=end[i];  	
  }
  for(int i=1;i<=N;i++){
  	if(i!=1)printf(" ");
  	start[i]--;
  	printf("%c%d",mp[start[i]/13],start[i]%13+1);
  }
  return 0;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值