刷pat的日子 乙级前十题

乙级B1001

/*
1001. 害死人不偿命的(3n+1)猜想 (15)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
卡拉兹(Callatz)猜想:

对任何一个自然数n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把(3n+1)砍掉一半。这样一直反复砍下去,最后一定在某一步得到n=1。卡拉兹在1950年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证(3n+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……

我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过1000的正整数n,简单地数一下,需要多少步(砍几下)才能得到n=1?

输入格式:每个测试输入包含1个测试用例,即给出自然数n的值。

输出格式:输出从n计算到1需要的步数。

输入样例:
3
输出样例:
5
*/
#include <iostream>
using namespace std;
long B1001_step = 0;
void B1001_Callatz(long n);
int main() {
	long n = 0;
	cin >> n;
	//B1001_Callatz(n);
	while (n != 1) {
		if (n % 2)n = (n * 3 + 1) / 2;
		else n /= 2;
		B1001_step++;
	}
	cout << B1001_step << endl;
    return 0;
}
void B1001_Callatz(long n) {
    if (n==1) {
        cout << B1001_step << endl;
    }
    else 
    {
        B1001_step++;
        if(n%2){
            n = (3 * n + 1) / 2;
            B1001_Callatz(n);
        }
        else 
        {
            B1001_Callatz(n/2);
        }
    }
}

好久没写题了,开始写的就是下面那个B1001_Callatz();函数,觉得 真复杂,百度一下 这也可以,然后就改成了while判断是不是结束了,也不用递归了~


乙级B1002

/*
1002. 写出这个数 (20)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字。

输入格式:每个测试输入包含1个测试用例,即给出自然数n的值。这里保证n小于10100。

输出格式:在一行内输出n的各位数字之和的每一位,拼音数字间有1 空格,但一行中最后一个拼音数字后没有空格。

输入样例:
1234567890987654321123456789
输出样例:
yi san wu
*/
#include <iostream>
#include "string.h"
using namespace std;
int main() {
	char n[100],transalte[5];
	char spell[10][5] = { "ling","yi","er","san","si","wu","liu","qi","ba","jiu" };
	gets_s(n);
	int len = strlen(n), sum = 0, digit = 0;
	for (int i = 0; i < len; i++) {
		sum += ((int)n[i]-48);
	}
	while (sum!= 0) {
		transalte[digit] = sum % 10;
		sum = sum / 10;
		digit++;
	}
	for (int i = digit-1; i >=0 ; i--) {
		cout << spell[transalte[i]] << " ";
	}
	cout << endl;
return 0;
}

熟悉了一下char类型字符串吧。

乙级B1003

/*
1003. 我要通过!(20)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于PAT的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。

得到“答案正确”的条件是:

1. 字符串中必须仅有P, A, T这三种字符,不可以包含其它字符;
2. 任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
3. 如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a, b, c 均或者是空字符串,或者是仅由字母 A 组成的字符串。

现在就请你为PAT写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。
输入格式: 每个测试输入包含1个测试用例。第1行给出一个自然数n (<10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过100,且不包含空格。

输出格式:每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出YES,否则输出NO。

输入样例:
8
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA
输出样例:
YES
YES
YES
YES
NO
NO
NO
NO
*/
#include <iostream>
#include "string.h"
using namespace std;
int main() {
	int num = 0, str_len = 0, Pleft_pos = 0, Tright_pos = 0, P = 0, A = 0, T = 0;
	bool flag = true;
	char str[10][100];
	cin >> num;
	for (int i = 0; i < num; i++) {
		cin >> str[i];
	}
	for (int i = 0; i < num; i++) {
		Pleft_pos = 0, Tright_pos = 0, P = 0, A = 0, T = 0, flag = true;
		for (str_len = 0; str_len < (int)strlen(str[i]); str_len++) { //check for P A T
			if (str[i][str_len] == 'P') {
				P++;
				Pleft_pos = str_len;
			}
			else if (str[i][str_len] == 'T') {
				T++;
				Tright_pos = str_len;
			}
			else if(str[i][str_len] != 'A'){
				flag = false;
				break;
			}
			A = str_len + 1 - P - T;
		}
		if (!flag||T!=1||P!=1||Tright_pos-Pleft_pos<2||(str_len-Tright_pos-1)<(Tright_pos-Pleft_pos-1)*Pleft_pos) {
			cout << "NO" << endl;
		}
		else {
			cout << "YES" << endl;
		}

	}
    return 0;
}

刚看到这个题目,还真的是傻得按条件筛选,首先看第一个条件,在第二个,,, 还是得百度 啧

第三步 和百度到的不一样,我理解为第三步是第二步的扩展,如果pt之间多一个A那么右边就多一个左边的a的字符串 嗯

乙级B1004

/*
1004. 成绩排名 (20)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
读入n名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。

输入格式:每个测试输入包含1个测试用例,格式为

第1行:正整数n
第2行:第1个学生的姓名 学号 成绩
第3行:第2个学生的姓名 学号 成绩
... ... ...
第n+1行:第n个学生的姓名 学号 成绩
其中姓名和学号均为不超过10个字符的字符串,成绩为0到100之间的一个整数,这里保证在一组测试用例中没有两个学生的成绩是相同的。
输出格式:对每个测试用例输出2行,第1行是成绩最高学生的姓名和学号,第2行是成绩最低学生的姓名和学号,字符串间有1空格。

输入样例:
3
Joe Math990112 89
Mike CS991301 100
Mary EE990830 95
输出样例:
Mike CS991301
Joe Math990112
*/


#include <iostream>
#include "string.h"
using namespace std;
int main() {
	char top_student_name[11], top_student_num[11], botton_student_name[11], botton_student_num[11], student_name[11], student_num[11];
	int Total_num = 0, top_score = 0, botton_score, score;
	cin >> Total_num;
	for (int i = 0; i < Total_num; i++) {
		cin >> student_name >> student_num >> score;
		if (i == 0) {
			strcpy_s(top_student_name, student_name);
			strcpy_s(top_student_num, student_num);
			top_score = score;
			strcpy_s(botton_student_name, student_name);
			strcpy_s(botton_student_num, student_num);
			botton_score = score;
		}
		else {
			if (score > top_score) {
				strcpy_s(top_student_name, student_name);
				strcpy_s(top_student_num, student_num);
				top_score = score;
			}
			else if (score < botton_score) {
				strcpy_s(botton_student_name, student_name);
				strcpy_s(botton_student_num, student_num);
				botton_score = score;
			}
		} 
	}
	cout << top_student_name << " " << top_student_num <<endl;
	cout << botton_student_name << " " << botton_student_num <<endl;
  return 0;
}

乙级B1005

/*
1005. 继续(3n+1)猜想 (25)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
卡拉兹(Callatz)猜想已经在1001中给出了描述。在这个题目里,情况稍微有些复杂。

当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数。例如对n=3进行验证的时候,我们需要计算3、5、8、4、2、1,则当我们对n=5、8、4、2进行验证的时候,就可以直接判定卡拉兹猜想的真伪,而不需要重复计算,因为这4个数已经在验证3的时候遇到过了,我们称5、8、4、2是被3“覆盖”的数。我们称一个数列中的某个数n为“关键数”,如果n不能被数列中的其他数字所覆盖。

现在给定一系列待验证的数字,我们只需要验证其中的几个关键数,就可以不必再重复验证余下的数字。你的任务就是找出这些关键数字,并按从大到小的顺序输出它们。

输入格式:每个测试输入包含1个测试用例,第1行给出一个正整数K(<100),第2行给出K个互不相同的待验证的正整数n(1<n<=100)的值,数字间用空格隔开。

输出格式:每个测试用例的输出占一行,按从大到小的顺序输出关键数字。数字间用1个空格隔开,但一行中最后一个数字后没有空格。

输入样例:
6
3 5 6 7 8 11
输出样例:
7 6
*/
//PAT 段错误!!!!!!!!!!!!!!!!!!!!!!!

#include <iostream>
using namespace std;
int main() {
	int list[101] = { 0 }, num, temp,i;
	cin >> num;
	for (i = 1; i <= num; i++) {
		cin >> temp;
		list[temp] = 1;
	}
	for (i = 1; i <= 100; i++) {
		if (list[i] == 1) {
			temp = i;
			while (temp != 1) {
				if (temp % 2)temp = (3 * temp) + 1;
				else temp /= 2;
				list[temp] = 0;
			}
		}
	}
	temp = 0;
	for (i = 100; i > 0; i--) {
		if (list[i] == 1) {
			if (temp == 0)
				cout << i;
			else
				cout << " " <<i;
			temp++;
		}
	}
  return 0;
}


/*
#include <stdio.h>
int main()
{
int K, n;
int tabel[101] = {0};
scanf("%d", &K);
for(int i = 0; i < K; i++)
{
scanf("%d", &n);
tabel[n] = 1;
}

// find numbers needed to test 
for (int i = 1; i <= 100; i++) if (tabel[i])
{
	// reuse variable n here 
	for (n = i; n > 1; )
	{
		// calculate one step
		if (n % 2)      n = (3 * n + 1) / 2;
		else           n /= 2;
		//see if the new number is in given numbers
		if (n <= 100 && tabel[n])
		{
			tabel[n] = 0;
			K--;                    //one less number not 'covered' 
			if (n < i) break;        //did this before, no need going on
		}
	}
}

for (int i = 100; i >= 1; i--) if (tabel[i] == 1)
{
	printf("%d%c", i, --K ? ' ' : '\0');
}

return 0;
}
*/
很难过最后一个样例 段错误 ??????????????    觉得比下面注释掉的好一点的是 不必要去判断数组下标数字是否出现过,直接赋值就好。不过 注释里那个最后的printf是真的第一次看到 嗯 记录学习

乙级B1006

/*
1006. 换个格式输出整数 (15)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
让我们用字母B来表示“百”、字母S表示“十”,用“12...n”来表示个位数字n(<10),换个格式来输出任一个不超过3位的正整数。例如234应该被输出为BBSSS1234,因为它有2个“百”、3个“十”、以及个位的4。

输入格式:每个测试输入包含1个测试用例,给出正整数n(<1000)。

输出格式:每个测试用例的输出占一行,用规定的格式输出n。

输入样例1:
234
输出样例1:
BBSSS1234
输入样例2:
23
输出样例2:
SS123
*/

#include <iostream>
using namespace std;
int main() {
	int num = 0, n;
	cin >> num;
	if (num / 100 != 0) {
		n = num / 100;
		for (int i = 0; i < n; i++) {
			cout << "B";
		}
		num = num % 100;
	}
	if (num / 10 != 0) {
		n = num / 10;
		for (int i = 0; i < n; i++) {
			cout << "S";
		}
		num = num % 10;
	}
	for (int i = 1; i <= num; i++) {
		cout << i;
	}
	cout << endl;
	return 0;
}

乙级B1007

/*
1007. 素数对猜想 (20)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
让我们定义 dn 为:dn = pn+1 - pn,其中 pi 是第i个素数。显然有 d1=1 且对于n>1有 dn 是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。

现给定任意正整数N (< 105),请计算不超过N的满足猜想的素数对的个数。

输入格式:每个测试输入包含1个测试用例,给出正整数N。

输出格式:每个测试用例的输出占一行,不超过N的满足猜想的素数对的个数。

输入样例:
20
输出样例:
4
*/


#include <iostream>
using namespace std;
int main() {
	int N = 0, num = 0, lastP = 0, i = 0;
	bool isP = false;
	cin >> N;
	for (i = N; i > 1; i--) {
		for (int j = 2; j <= i - 1; j++) { //check if is p
			if (i%j == 0) {
				isP = false;
				break;
			}
			isP = true;
		}
		if (isP) {
			if (lastP == 0) {
				lastP = i;
				continue;
			}
			if ((lastP - i) == 2) {
				num++;
			}
			lastP = i;
		}
		isP = false;
	}
	cout << num << endl;
	return 0;
}

最后一个样例超时了修改了个判断素数的函数时间复杂度从o(n)到o(logn)

#include <iostream>  
using namespace std;  
int prime(int a) {  
    if(a % 2 == 0 && a != 2) {  
        return 0;  
    }  
    for(int i = 3; i * i <= a; i++) {  
        if(a % i == 0) {  
            return 0;  
        }  
    }  
    return a != 1;  
}  
int main() {  
    int N = 0, num = 0, lastP = 0, i = 0;  
    cin >> N;  
    for (i = N; i > 1; i--) {  
        if (prime(i)) {  
            if (lastP == 0) {  
                lastP = i;  
                continue;  
            }  
            if ((lastP - i) == 2) {  
                num++;  
            }  
            lastP = i;  
        }   
    }  
    cout << num << endl;  
    return 0;  
}  

乙级B1008

/*
1008. 数组元素循环右移问题 (20)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A0 A1……AN-1)变换为(AN-M …… AN-1 A0 A1……AN-M-1)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?

输入格式:每个输入包含一个测试用例,第1行输入N ( 1<=N<=100)、M(M>=0);第2行输入N个整数,之间用空格分隔。

输出格式:在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。

输入样例:
6 2
1 2 3 4 5 6
输出样例:
5 6 1 2 3 4
*/


#include <iostream>
#include <algorithm>
using namespace std;
int main() {
	int  len = 0, right = 0;
	cin >> len >> right;
	int *list = new int[len];
	for (int i = 0; i < len; i++) {
		cin >> list[i];
	}
	right %= len;//if right is bigger than len
	reverse(list, list + len - right);
	reverse(list + len - right, list + len);
	reverse(list, list + len);
	for (int i = 0; i < len; i++) {
		if (i == 0) {
			cout << list[i];
		}
		else {
			cout << " " << list[i];
		}
	}
	delete[] list;
	/*
	for (int i = len-right; i < len; i++) {
		cout << list[i]<<" ";
	}
	for (int i = 0; i < len - right - 1; i++) {
		cout << list[i] << " ";
	}
	cout << list[len - right - 1];
	*/
	return 0;
}

reverse函数练习一遍 说来这个都不用算法注释掉的那段直接就完事了 啧

乙级B1009

/*
1009. 说反话 (20)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。

输入格式:测试输入包含一个测试用例,在一行内给出总长度不超过80的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用1个空格分开,输入保证句子末尾没有多余的空格。

输出格式:每个测试用例的输出占一行,输出倒序后的句子。

输入样例:
Hello World Here I Come
输出样例:
Come I Here World Hello
*/


#include <iostream>
#include "cstdio"
using namespace std;
int main() {
	int num = 0;
	char sentences[80][100];
	while (scanf("%s", sentences[num]) != EOF) {
		num++;
	}
	for (int i = num - 1; i >= 0; i--) {
		cout << sentences[i];
		if (i > 0) {
			cout << " ";
		}
	}
	return 0;
}

乙级B1010

/*
1010. 一元多项式求导 (25)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
设计函数求一元多项式的导数。(注:xn(n为整数)的一阶导数为n*xn-1。)

输入格式:以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。

输出格式:以与输入相同的格式输出导数多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。注意“零多项式”的指数和系数都是0,但是表示为“0 0”。

输入样例:
3 4 -5 2 6 1 -2 0
输出样例:
12 3 -10 1 6 0
*/

#include <iostream>
using namespace std;
int main() {
/*	int a, b, lastb=0, first = 0;
	while (true) {
		cin >> a >> b;
		if (b > lastb) {
			first = 0;
		}
		if (first == 0) {
			if (b > 1) {
				cout << a * b << " " << b - 1;
				lastb = b;
			}
			else {
				cout << "0 0";
				lastb = -1;
			}
			first = 1;
		}
		else {
			if (b >= 1) {
				cout << " " << a * b << " " << b - 1;
				lastb = b;
			}
			else lastb = -1;
		}
	}
//运行超时啦啦啦啦
*/
    int a, b;
    bool first = true;
    while (cin>>a>>b) {
        if (b!=0&&a!=0) {
            if (!first) {
                cout<<" ";
            }
            cout<<a*b<<" "<<b-1;
            first = false;
        }
    }
    if (first) {
        cout<<"0 0";
    }
return 0;
}



乙级还是很基础 赶紧刷 为什么荒了四年

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冬天为什么这么冷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值