pat 乙级 1001~1010

文章目录

1001
1002
1003
1004
1005
1006
1007
1008
1009
1010


1001

解题思路:

用while+if-else来控制循环次数(砍得的次数)和判断奇数偶数

参考代码:

#include <iostream> 
using namespace std;

int main()
{
	int n,step=0;
	cin >> n;
	while(n!=1)
	{ 
		if(n%2==0)
			n/=2;
		else
			n=(3*n+1)/2;
		step++;
	} 
	cout << step;
	return 0;
}

别人代码:

#include <iostream>
using namespace std;
int main() {
 int n, count = 0;
 cin >> n;
 while (n != 1)
  {
	 if (n % 2 != 0)      //这个循环就是判断奇数的,n为奇数*3+1完了,在下一句除2 这样就省掉了加括号的麻烦 抓住了不管奇数还是偶数                         
//都有除2的特点 如果n为偶数不执行此语句,直接再下面除2
		 n = 3 * n + 1;   
	 n = n / 2;
	 count++;
 }
 cout << count;
 return 0; }

1002

解题思路:

1.用string类来存储数据,不然的话double,long long类型的长度不够

2.用for循环来计算各位数字之和

3.用string类定义一个数组,其中成员是数字的拼音

4.将数字和变量改为字符串类型,方便调用每个位数字,不用对数字除或求余

5.通过循环从数字和的字符串中对应找到string类的数字拼音

参考代码:

#include<iostream>
using namespace std;

int main()
{
	string s;
	cin >> s;
	int i,sum=0;
	for(i=0; i<s.length(); i++)     //s.length()计算字符串长度 
	{
		sum+=s[i]-'0';
	}
	string name[10]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};  //字符串用双引号括起来,字符用单引号括起来 
	
	string a = to_string(sum);
	
	for(i=0; i<a.length(); i++)
	{
		cout << name[a[i]-'0'];   //将数字转变为字符去存储方便调用每个位置上的数字,不用再除或求余啥的 
		if (i != a.length()-1)
			cout << ' ';
	}
	

	return 0;
}

别人代码:

#include <iostream>
#include <string>
using namespace std;
int main() 
{
	 string s;
	 cin >> s;
	 int sum = 0;
	 string str[10] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi","ba", "jiu"};   //
	 for (int i = 0; i < s.length(); i++)
	 	sum += (s[i] - '0');
	 	
	 string num = to_string(sum);
	 
	 for (int i = 0; i < num.length(); i++)
	 {
		 if (i != 0)        //题目要求最后一个拼音不能有空格,所以是先输出拼音,后输出空格,提前加一个if判断,当输入完最后一个拼音,循环都已经结束了
		 	cout << " ";
		 cout << str[num[i] - '0'];
	 }
	 
	 return 0; 
 }

1003

解题思路:

1.本题难点在于找规律,首先明确一点不是AAA…AAPAA…AATAA…AA这么简单的规律。

2.突破点在于aPbTc正确和aPbATca正确,显然第二个在P与A之间多加了一个A,后面多了一个a,而a又是第一个的P之前的部分,其实这里a,b,c均是狗(宇哥替换)。观察例子:AAPATAA与AAPAATAAAA,这里a相当于AA,b相当于A,c相当于AA。在第二个中P,T之间多加了A,则后面多加AA。所以规律是在P,T之间多加一个A,则原来字符串T后面多 补充 原来字符串P之前的部分。比如对于AAPAATAAAA而言,AAPAAATAAAAAA也是对的,AAPAAATAAAAAAAA也是对的。

3.如果P之前没有A,则无论在P,T之间加多少的A,T之后也不会有A,所以形如PAAA…AAAT都对

4.xPATx这种形式告诉我们,AAA…AAAPATAAA…AAA是可以的,只要PAT前和后的AAA对称。二一个当x为空格是PAT也是正确。

5.通过例子可知有且仅有P,A,T三种字符,其中P,T的个数只能为1,而A的个数不能0,P,T之间至少一个A,对于APAAATAA我们可知可以由APAATA得来,但是例子表示APAAATAA是错误,所以APAATA也是错误

6.总之,就是P之前A的个数*P与T之间A的个数等于T之后A的个数 (这规律我估计也不是他想出来的,或者就是偶然想到的

参考代码:

#include<iostream>
#include<map>
using namespace std;

int main()
{
	int n,i,j,p,t;
	cin >> n;
	string s;
	for(i=0; i<n; i++)
	{
		cin >> s;
		map<char, int > m;
		for(j=0; j<s.length(); j++)
		{
			m[s[j]]++;
			if(s[j]=='P')
				p=j;
			if(s[j]=='T')
				t=j;
		}
		if(m['P']==1 && m['A']!=0 && m['T']==1 && m.size()==3 && t-p!=1 && p*(t-p-1)==s.length()-t-1)
			cout << "YES" << endl;
		else
			cout << "NO" << endl;
	}
	return 0;
}

1004

解题思路:

1.首先根本不用存储每次输入的学生的信息,重点是要知道成绩最值的学生的姓名和学号,所以用变量来存储这些信息。“铁打的营盘流水的兵”恰如其分描述铁打的营盘类似成绩最值的姓名和学号,而流水类似不断敲入的学生成绩,姓名和学号

参考代码:

#include <iostream>
using namespace std;
int main() {
 int n, max = -1, min = 101, score;
 cin >> n;
 string maxname, minname, maxnum, minnum, name, num;
 for (int i = 0; i < n; i++) {
 cin >> name >> num >> score;
 if (max < score) {
 max = score;
 maxname = name;
 maxnum = num;
 }
 if (min > score) {
 min = score;
 minname = name;
 minnum = num;
 }
 }
 cout << maxname << " " << maxnum << endl << minname << " " << minnum;
    return 0; }

1005

解题思路:

1.设置一个数组arr[]其中表示对输入数字进行c式处理后对应下标为1
比如:输入5 ,第一次c式处理后为8,则将arr[8]的值为1
先判断arr值是否为1,是则退出循环,输入下一个值判断,不是另其值为1

2.注意arr数组的空间大小为10000否则只是部分正确

参考代码:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int arr[10000];
bool cmp(int a, int b)
{
    return a>b;
}

int main()
{
    int k,n,flag=0;
    cin >> k;
    vector<int> v(k);//定义一个数组
    //for中嵌套while,外面一共循环k次,里面就是对数字处理并且标记对应arr数组中的值为1
    //如果在while中判断数字有1则直接输入下一个数
    for(int i=0; i<k; i++)
    {
        cin >> n;
        v[i]=n;   //数组存放对应的数字
        while(n!=1)
        {
            if(n%2!=0)
                n=3*n+1;
            n/=2;
            /*?*/
            if(arr[n]==1)
                break;
            arr[n]=1;
        }
    }
    sort(v.begin(), v.end(), cmp); //将数组按照从大到小的顺序排列
    for(int i=0; i< v.size(); i++)
    {
        if(arr[v[i]]==0) //表示
        {
            if(flag==1)
                cout << " ";
            cout << v[i];
            flag=1;

        }
    }
    return 0;
}


1006

解题思路:

就是取百位然后循环输出B,求出十位循环输出S,求出个位循环输出1–n

参考代码:

#include<iostream>
using namespace std;
/*
    思路就是取百位然后循环输出B,求出十位循环输出S,求出个位循环输出1--n
*/
int main()
{
    int n;
    cin >> n;
    for(int i=1; i<=n/100; i++)
        cout << 'B';
    for(int j=1; j<=n%100/10; j++)
            cout << 'S';
    for(int k=1; k<=n%10; k++)
            cout << k;
    return 0;
}


1007

解题思路:

ans表示有多少对数字
遍历从0–n相邻且相差2的数字,然后判断是否为素数

参考代码:

#include<iostream>
using namespace std;
/*
  解题思路:ans表示有多少对数字
        遍历从0--n相邻且相差2的数字,然后判断是否为素数
*/
int f(int n)
{
    for(int i=2; i*i<=n; i++)
        if(n%i==0)
            return 0;
    return 1;
}
int main()
{
    int n,ans=0;
    cin >> n;
    for(int i=2; i<=n-2; i++)
    {
        if(f(i) && f(i+2))
            ans++;
    }
    cout << ans;
    return 0;
}


1008

解题思路:

先把数组倒叙,再把前m为倒叙,再把后面的倒叙即可。(客观规律,记住即可)
之前的思路是向后移数组,在把超出部分放到前面,但这样部分正确。我分析是:使用太多的数组,因为题目要求程序移动的次数竟可能少

参考代码:

#include<iostream>
#include<algorithm>  //reverse()使用此头件
#include<vector>  //vector使用此头文件
using namespace std;
int main()
{
    int n,m;
    cin >> n >> m;
    vector<int > a(n);
    for(int i=0; i<n; i++)
        cin >> a[i];
    m%=n;
    if(m!=0)
    {
        reverse(a.begin(),a.end());  //a.begin()是指针,指向数组第一个元素;a.end()也是指针,指向a[6]
        reverse(a.begin(),begin(a)+m);  //reverse中不会将第2部分的值也倒转,而是把他之前的值倒转
        reverse(begin(a)+m,a.end());  //从上一位置开始
    }
    for(int i=0; i<n-1; i++)
        cout << a[i] << " ";
    cout << a[n-1];
    return 0;
}


1009

解题思路:

利用栈先进后出的思想来倒叙输出字符串
首先,将字符串压入栈,访问栈顶元素,弹出当前栈顶元素。
由于题目要求,字符串之间有空格并且最后一个字符串没有空格,下面就循环先输出空格再输出字符串然后弹出

参考代码:

#include<iostream>
#include<stack>
using namespace std;

int main()
{
    stack<string> v;
    string s;
    while(cin >> s)
        v.push(s);
    cout << v.top();
    v.pop();
    while(!v.empty())
    {
        cout << " " << v.top();
        v.pop();
    }
    return 0;
}

1010

解题思路:

1.每次输入两个变量,不用存放到数组中,规律是每次输出第一个变量*第二个变量;第二个变量-1

2.对于上面规律使用前提是第二个变量不为0,若为0,不执行语句,进入下一次循环,看,在这里并不是

3. 使用continue,而是循环中嵌套一个if,这样当条件不满足时,自动不执行if中的语句,直接进入下一次循环

4.对于先输出数值,后输出空格,但在最后不能有空格的套路是用flag标记(你懂的)

5.对于零项多项式和全部都是常数项而言,当整个循环结束后还是用flag==0判断,并输出0 0

参考代码:

#include<iostream>
using namespace std;
int main()
{
    int flag=0;
    int a,b;
    while(cin >> a >> b)
    {
        if(b!=0)
        {
            if(flag==1)
                cout << " ";
            cout << a*b << " " << b-1;
            flag=1;
        }
    }
    if(flag==0)
        cout << "0 0";
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值