PTA刷题总结

L1-002 打印沙漏:
https://pintia.cn/problem-sets/994805046380707840/problems/994805145370476544
解读1:
本题首先结构大致是一个等差数列 *2 再减去多余的只有一个字符的那一列
在这里插入图片描述
即每一组的字符总数为 2Sn-1

解读2:
做这道题时陷入了一个思维陷阱里,首先我们每一层最后的两格空格不用考虑 直接回车即可
其次是直接打印即可 不需要把值存到二维数组中
最后是 前面每一层的空格数跟该层层数是有关系的 字符数也是与层数有关

假如一共是3层

***** 第一层 空格数0 
 ***  第二次 空格数1
  *   第三层 空格数2
 *** 
*****


#include
#include
using namespace std;
int main(){
    int a[25]={0};
    
    for(int i=1;i<25;i++){ 
        a[i]=2*i*i-1; //见解读1
    }
    
    for(int j=1;j<24;j++) cout<<a[j]<<" ";
    cout<<endl;
    int n;//n<=1000
    char c;
    scanf("%d %c",&n,&c);

    int les;
    int h;
    for(int i=1;i<25;i++){
        if(n-a[i]<0){
            les=n-a[i-1];//多余的字符数
            h=i-1;//层数
            break;
        }
    }
    //打印 细节见解读2
    for(int i=1;i<=h;i++){
        for(int j=1;j<i;j++){
            printf(" ");
        }
        for(int k=1;k<=2*h+1-2*i;k++){
            printf("%c",c);
        }
        printf("\n");
    }
    for(int i=1;i<=h-1;i++){
        for(int j=1;j<h-i;j++){
            printf(" ");
        }
        for(int k=1;k<=2*i+1;k++){
            printf("%c",c);
        }
        printf("\n");
    }
    printf("%d\n",les);
    return 0;
}

L1-003 个位数统计
https://pintia.cn/problem-sets/994805046380707840/problems/994805143738892288
这道题比较简单
注意点:
1、如果存在字符数组里,记得给字符数组所有空间的值改为一个不是个位数字的符号


L1-005 考试座位号

回顾一下字符数组的输入方式
https://blog.csdn.net/a834352982/article/details/56841873

还碰到了一个问题就是我用字符数组 gets()方法在PAT中不支持 显示未定义
则改为cin.getline(s,n)的形式

再测试发现有两个测试点错误

这道题我想的字符数组存
字符数组方法:https://blog.csdn.net/sunshineacm/article/details/79451730
还可以是结构体。。。


L1-006 连续因子
https://pintia.cn/problem-sets/994805046380707840/problems/994805138600869888
这道题在题意理解上要格外注意

又是一道乘法的数学问题!(每次栽在数学问题上)
涉及到 素数 余数


作者:18Temp 来源:CSDN 原文:https://blog.csdn.net/qq_37729102/article/details/80712640
版权声明:本文为博主原创文章,转载请附上博文链接!

从1乘到N,每乘一次判定当前乘积prd是否为N的因子,即N%prd是否为0,若为0,比较上一次乘积因子序列的长度,若大于,则记录。
不断更新乘积因子序列长度,直到最后一个因子为N。当然,最需要注意的是最外层的循环变量i判定条件必须为i<=sqrt(n),如果是i*i<=n,则最后一个测试点会不过。本人猜测可能是平台的问题。虽然看上去很暴力,但此算法最后一个测试点耗时仅5ms

#include
#include
using namespace std;
typedef long long ll;
int main()
{
	ll n;
	cin>>n;
	ll prd=0;//定义乘积 
	int start=0,len=0;//定义最终得到序列开始的因子,序列的长度 
	for(int i=2;i<=sqrt(n);i++)//i从2到根号n 
	{
		prd=1;
		for(int j=i;prd*j<=n;j++)//从j开始一直乘到N为止,每次乘积判定是否小于等于N,若超过N,则结束循环 
		{
			prd*=j;//乘积迭代 
			if(n%prd==0&&j-i+1>len)//如果当前乘积为N的乘积因子且长度大于上一次 
			{//更新序列起始因子和长度 
				start=i;
				len=j-i+1;
			}
		}
	}
	if(start==0)//若起始因子为0,说明N为质数,因为质数=1*本身,而循环最多能表示1*本身的根号 
	{
		start=n;
		len=1;
	}
	cout<<len<<'\n'<<start;
	for(int i=start+1;i<start+len;i++)//输出,如果因子只有一个只输出一个 
	cout<<'*'<<i;
	return 0;
}

由此,我发现我把题意弄错了 以为是输出最大序列长度和输出最小长度序列的值(傻了 。。最小序列不就是它自己嘛


L1-007 念数字
被0坑了啊 一定要注意特殊情况 还有格式要严格遵循!尤其是空格 坑死我了

#include
#include 
using namespace std;
int main()
{
	
	char a[11][5] ={{"ling"},{"yi"},{"er"},{"san"},{"si"},{"wu"},{"liu"},{"qi"},{"ba"},{"jiu"}};

	
	int b;
	cin>>b;
	int num[1001]; int z=0;
	if(b==0){cout<<"ling";	} //0
	if(b<0){b*=-1;cout<<"fu ";}//负数时转化成正数并输出fu
		while(b)
	{	
		num[z]=b%10;
		b/=10;
		z++;
	} 
	//b=1234时 num[..]=4321;
	for(int j=z-1;j>=0;j--)
	{
		if(j==0)cout<<a[num[j]];
		else cout<<a[num[j]]<<" ";
		//对于格式的详细分化
	}
	return 0;
}


L1-008 求整数段和

一道很简单的题做了很久。。。里面有很多坑。
首先求和没什么问题。

感觉到c语言比c++便利很多啊
总结:好好学C

#include
int main()
{
    int a,b,i,cot=0,sum=0;//添加计数器
    scanf("%d %d",&a,&b);//输入区间

    //以a为起点,如果a小于b,每次a累加1
    for(i=a;i<=b;i++){
        printf("%5d",i);//题目要求占5个字符宽
        cot++;//每输出一次,计数器累加1
        if(cot%5==0&&i!=b)//如果当前计数器的值能被5整除那么换行 注意不要多输出一个回车了
            printf("\n");
            }
       printf("\n");//执行完循环后,换行输入总和
   for(i=a;i<=b;i++)
        sum+=i;
   printf("Sum = %d",sum);

   return 0;

}


L1-009 N个数求和
注意认真看题目:负数的符号一定出现在分子前面

这个题有几种情况
1、首先判断分子是不是0,如果是的话说明最终结果是0
2、还有最大公约数 最基本的算法问题
也就是辗转相除法 gcd(a,b) = gcd(b,a mod b)。直至余数=0 最大公约数则为M

int Gcd(unsigned int M,unsigned int N)
{
unsigned int Rem;
while(N > 0)
{
Rem = M % N;
M = N;
N = Rem;
}
return M;
}

3、if(n==0) printf(“0\n”);

https://blog.csdn.net/qq_37729102/article/details/80713906


L1-011 A-B
我想的很麻烦 写的也不对 难受。。。
以下是大神代码 思路很清晰 ——数组一一对应 类似映射的方法

#include
#include
#include
 
int main()
{
	char a[10001];
	char b[10001];
	int c[128];
	int i;
	gets(a);
	gets(b);
	for(i=0;i<128;i++)
	{
	  c[i]=0;	
	}	
	for(i=0;i<strlen(b);i++)
	{
		c[(int)b[i]]=1;
	}
	for(i=0;i<strlen(a);i++)
	{
		if(c[(int)a[i]]==0)
		  printf("%c",a[i]);
	}
	printf("\n");
	return 0;
 } 


L1-012 计算指数
很简单 注意类型的定义。。

#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
int main()
{
    long long n;
    cin>>n;
    cout<<2<<'^'<<n<<" = "<<pow(2,n)<<endl;
    return 0;
}

L1-015 跟奥巴马一起画方块
简单。。判断n是不是奇数 如果是 列数等于n++/2


L1-016 查验身份证

有一个坑是定义char a[ ][ ]时
用scanf("%s",a[i]);输入每一行时最后都会加入一个换行符进去 所以要多留一个空 否则会出现很奇怪的错

还要注意向char数组和int数组放入数字 再取出来是不一样的
char数组取出来转变成int还需要减去’0’

#include
#include
#include
#include
#include
#include
#include
using namespace std;


int main()
{
    int n;
    cin>>n;
    char a[n][19];//存放身份证
    int q[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};//权值
    char z[11] = {'1','0','X','9','8','7','6','5','4','3','2'};//对应校验码
    int s[100]={0};//标志 如果有问题的就为1 将为1的输出
    int flag=0;//如果没有有问题的身份证 就输出all pass
    for(int i=0;i<n;i++)
    {

        scanf("%s",a[i]);
        int sum=0;
        for(int j=0;j<17;j++)
        {
            int t;

            t=(int)a[i][j]-'0';

            if(t<0||t>9){s[i]=1;sum=0;break;} //为字母时

            sum+=(t*q[j]);
            //cout<
        }
        if(sum){
                sum%=11;
                if(z[sum]!=a[i][17])s[i]=1; 
        }//有问题

    }


   for(int k=0;k<n;k++)
   {
       if(s[k]){printf("%s\n",a[k]);flag=1;}//并不是全没问题 
   }


    if(!flag)cout<<"All passed"<<endl;//全没问题时输出


    return 0;
}

L1-017 到底有多二
用C语言方式使字符数组可以一次性输入一整行

scanf("%s",a); //a[i] i为行数

#include
#include
#include
#include
using namespace std;
int main(){
	string s;
	int len,m=0;//长度 ,2的个数
	double i=1.0;//程度
	cin>>s;
	
	if(s[0]=='-')
	i=i*1.5;//注意是*不是+0.5
	len=s.size();
    //	cout<
	if((s[len-1]-48)%2==0)
	  i=i*2;
	  
	  for(int j=0;j<len;j++){
	  	if(s[j]=='2'){
	  		m++;
		  }
	  }
	  if(s[0]=='-')
	   len--;
	//cout<
	double w=(double)((double)m/len)*i*100;
	printf("%.2lf%%\n",w);
	return 0;
} 

佛了 写了多少遍 按照别人的代码一个个对还是有问题
注意 1char里面的数字和int 里的数字是不一样的!
	2、倍数是要乘起来的
	3、相乘 数据类型注意一致

L1-018 大笨钟
很简单 一次过。。

#include
#include
#include
#include
#include
#include
#include
using namespace std;

void c (int n){
	for(int i=0;i<n;i++)
	cout<<"Dang";
	cout<<endl;
} 

int main()
{
   int h;
   cin>>h;
   getchar();
   int t;
   cin>>t;
   int time[4]={0};
   	if(h>10){
   		time[0]=h/10;
   		time[1]=h%10;
	   }
	   else time[1]=h;
	   if(t>10){
   		time[2]=t/10;
   		time[3]=t%10;
	   }
	   else time[3]=t;
    if(h>=0&&h<=12)cout<<"Only "<<time[0]<<time[1]<<":"<<time[2]<<time[3]<<".  Too early to Dang."<<endl;
    else if(t>0)c(h+1-12);
    else c(h-12);
	
    return 0;
}

L1-019 谁先倒
一开始被数组开小坑了,显示“段错误”,改大之后就可以了
很简单。。。

#include
#include
#include
#include
#include
#include
#include
using namespace std;

int main()
{
	int aj,bj; int asum=0,bsum=0;
	cin>>aj>>bj;
	int n;
	cin>>n;
	int a[200],b[200];
	for(int i=0;i<2*n;i+=2)
	{
		cin>>a[i]>>a[i+1];
		cin>>b[i]>>b[i+1];
		int sum=a[i]+b[i];
		if(aj>=0&&bj>=0){
			if(a[i+1]!=sum&&b[i+1]!=sum)continue;
			else if(a[i+1]==sum&&b[i+1]==sum)continue;
			else {
				if(a[i+1]==sum) {
					aj--;asum++;
				}
				else {
					bj--;bsum++;
				}
			}
		}
		
	}
	
	if(aj<0){cout<<'A'<<endl;cout<<bsum<<endl;
	}
	else {cout<<'B'<<endl;cout<<asum<<endl;
	}
	
    return 0;
}

L1-020 帅到没朋友
我想的思路实现起来好麻烦。。。
看一下别人的代码

#include  
int main()  
{  
    int Person[100000]={0};  
    int N,n,m,K,i,j,sum=0;  
    scanf("%d",&N);  
    for(i=1;i<=N;i++)  
    {  
        scanf("%d",&n);  
        for(j=1;j<=n;j++)  
        {  
            scanf("%d",&m);   
            if(n!=1)  //=1肯定没朋友
            Person[m]+=n;  //用数组标记即可
        }  
    }  
    scanf("%d",&K);  
    for(i=1;i<=K;i++)  
    {  
        scanf("%d",&m);    
        if(Person[m]==0)  
        {  
            if(sum!=0)  
                printf(" ");  //没有全输出完时都要输出空格 用于隔开
            printf("%05d",m);  
            //避免多次被检测  
            Person[m]=-1;  
            sum++;  //有没朋友的人
        }  
    }   
    if(sum==0)  //都有朋友时sum==0
        printf("No one is handsome");  
    printf("\n");  
    return 0;  
}  


L1-023 输出GPLT

#include
#include
#include
#include
#include
#include
#include
using namespace std;


int main()
{
   int n[4]={0};
   char c;
   while((c=getchar())!='\n'){ //注意这个是使getchar结束符为换行
   		if(c=='g'||c=='G') n[0]++;
   		else if(c=='p'||c=='P') n[1]++;
   		else if(c=='l'||c=='L') n[2]++;
   		else if(c=='t'||c=='T') n[3]++;
   		else continue;
   }
   	
   		int sum=n[0]+n[1]+n[2]+n[3];
	for(;sum;)
	{	sum=n[0]+n[1]+n[2]+n[3];
		if(n[0]){
			cout<<"G";
			n[0]--;
		}
		
		if(n[1]){
			cout<<"P";
			n[1]--;
		}
	
		if(n[2]){
			cout<<"L";
			n[2]--;
		}
		if(n[3])
		{
			cout<<"T";
			n[3]--;
		}
				
		}
	cout<<endl;
    return 0;
}



L1-025 正整数A+B
这道题有一个坑是A可以是一个空串 并且 b可以是一个空格组成的串
所以我们定义的string b 输入方式改成getline(cin,b); 就可以输入空格串啦

#include
#include
#include
#include
#include
#include
#include
using namespace std;

int f(string a){
	for(int i=0;i<a.length();i++)
	{
		if(a[i]<48||a[i]>57)return 0;
	}
	return 1;
}
int s(string a){
	int sum=0;
	int k=1;
	for(int j=a.length()-1;j>=0;j--)
	{
		int xs=0;
		xs+=(int)a[j];
		xs-=48;
		xs*=k;
		sum+=xs;
		k*=10;
	}
	return sum;
}
int main()
{
  string a,b;
  a="";
  int absum=0;
  char c;
  c=getchar();
  while(c!=' '&&c!='\n'){
  	a+=c;
  	c=getchar();
  }
  
  getline(cin,b);
  if(f(a)==0)a="?";
  if(f(b)==0)b="?";
  if(s(a)>1000||s(a)<1) a="?";
  if(s(b)>1000||s(b)<1) b="?";
  
  if(a!="?"&&b!="?"){
  
  	absum=s(a)+s(b);
  	cout<<a<<" + "<<b<<" = ";
  	cout<<absum<<endl;
  	
  }
  else 	{
  		cout<<a<<" + "<<b<<" = ?";
  		
  }
  
    return 0;
}



L1-027 出租
实现上有点麻烦,其他没什么问题

#include
#include
#include
#include
#include
#include
#include
using namespace std;
bool compare (int a,int b)
{
	return a>b;
}

int main()
{
  char  p[11];
  int arr[11]={0};
  char farr[11];
  int sum=0;int dsum=0;
  scanf("%s",p);
  for(int i=0;i<=10;i++)	
	{	int  c=(int)p[i]-'0';
		if(arr[c]==0) {
			arr[c]=1;
			farr[sum]=p[i];
			sum++;
			
		}
	}
	dsum=sum;
	sort(farr,farr+sum,compare);
	cout<<"int[] arr = new int[]{";
 	for(int z=10;z>=0;z--)
	{
		if(arr[z]==1){
			cout<<z;
			dsum--;
		}
		else continue;
		if(dsum)cout<<",";
	}	
	cout<<"};"<<endl;
	cout<<"int[] index = new int[]{";
	for(int q=0;q<11;q++)
	{
		int pp=0;
		while(p[q]!=farr[pp])pp++;
		cout<<pp;
		if(q!=10)cout<<',';
	}
	cout<<"};"<<endl;
    return 0;
}

L1-030 一帮一
实现上用了很长时间,还需要锻炼

#include
#include
#include
#include
#include
#include
#include
using namespace std;

struct person{
	bool sex;
	string name;
	bool h;
};
int main()
{	
	int n;
	cin>>n;
	person p[n];
	
	for(int i=0;i>p[i].sex;
		cin>>p[i].name;
		p[i].h=1;//未分配 
	}
	int sum=n;
	int  j=0;
		for(int k=n-1;k>0&∑k--)
		{
			if(p[j].sex!=p[k].sex&&p[j].h&&p[k].h){
				cout<

L1-032 Left-pad
想复杂了 直接输出就可以 之前还在想怎么把数组里面处理成结果的样子呜呜
在这里插入图片描述
这啥意思???
%d 整型

%* 忽略
%c 带表示忽略 就是说,在输入流中,读取一个字符

scanf("%[^\n]%*c",str)
表示读入一行字符串。
^ 表示"非",[^\n]表示读入换行字符就结束读入。


L1-033 出生年

#include
#include
#include
#include
#include
#include
#include
using namespace std;

int num(int y)
{
	int k=0;
	int sum[10]={0};
	int a=y%10;
	int b=y%100/10;
	int c=y%1000/100;
	int d=y/1000;
	sum[a]++;
	sum[b]++;
	sum[c]++;
	sum[d]++;
	//cout<
	//cout<
	for(int i=0;i<10;i++)
	{
		if(sum[i])k++;
		
	}
	return k;
}

int main()
{	
	int y,n,year;
	cin>>y>>n;
	year=y;
	for(;year<4000;year++){
		if(num(year)==n){
			if(year<10){
			cout<<year-y<<" 000"<<year<<endl;
			break;
			}
			else if(year<100){
			cout<<year-y<<" 00"<<year<<endl;
			break;
			}
			else if(year<1000){
			cout<<year-y<<" 0"<<year<<endl;
			break;
			}
			else {
			cout<<year-y<<" "<<year<<endl;
			break;
			}
			
		}
	}
    return 0;
}

你可能感兴趣的:(数据结构)