【PTA刷题整理】PAT 乙级 1008 数组元素循环右移问题 + 1009 说反话

2020.02.24 终于开始上课了,第一周进行网上教学的测试,做题的时间没那么多了,只能先做这乙级的题目


1008 数组元素循环右移问题 (20分)

一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A​0​​A​1​​⋯A​N−1​​)变换为(A​N−M​​⋯A​N−1​​A​0​​A​1​​⋯A​N−M−1​​)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?
输入格式:

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

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

6 2
1 2 3 4 5 6
输出样例:

5 6 1 2 3 4


题意不难理解,就是按照要求依次右移,多出来的部分补位到前面移出的空位中,值得注意的是,对于M大于N的情况可以通过求余来简化
思路为第一步以要溢出位为界限(下面用“||”划开)
先将右侧的数(即第N - M到第N - 1位)做对称换位
如样例
1 2 3 4 || 6 5
第二步再将左侧的数(即第0到第N - M - 1位)做对称换位
4 3 2 1 || 6 5
最后对整体进行对称换位得到答案
5 6 1 2 3 4
所以核心就是这个对称换位怎么写了,传入要换位区间的左右两端,折半(不然的话前面换过去,后面又换回来了等于没做)使用中间变量交换首位对应位置的数就好啦


#include<iostream>                  //输入输出流头文件
#include<stdio.h>                   //标准输入输出
#include<stdlib.h>
#include<math.h>                    //数学函数
#include<string.h>                  //C语言字符数组的字符串
#include<algorithm>                 //C++标准模板库的函数
#include<map>                       //map映射容器
#include<unordered_map>             //无序的map映射容器
#include<vector>                    //变长数组容器
#include<queue>                     //队列
#include<stack>                     //栈
#include<string>                    //C++string类
#include<set>                       //set集合
using namespace std;                //标准命名空间

                                    //可以加入全局变量或者其他函数

void reverse(int a[], int l, int r){
    int temp; 
    for(int i = l;i <= (l + r)/2 ;i++){ 
        temp = a[i];
        a[i] = a[r + l - i];
        a[r + l -i] = temp;
    }
}

int main(){                         //主函数
#ifdef ONLINE_JUDGE                 //如果有oj系统(在线判定),则忽略文件读入,否则使用文件作为标准输入
#else
    freopen("1.txt", "r", stdin);   //从1.txt输入数据
#endif
	int N, M;
    cin >> N >> M;
    int num[N];
    for(int i = 0;i < N;i++){
        cin >> num[i]; // 输入
    }
    M %= N;       
    reverse(num, N - M, N - 1);
    reverse(num, 0, N - M - 1);
    reverse(num, 0, N - 1);
            
    for(int i = 0 ; i < N ; i++){
    	if(i == N - 1){
    		cout << num[i] << endl;
    		break;
		}
        cout << num[i] << " ";
    }
        
    return 0;                       
}


1009 说反话 (20分)

给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。
输入格式:

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

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

Hello World Here I Come
输出样例:

Come I Here World Hello


说实话对于字符串的题目和函数的应用真的超级不熟悉擅长,花了很长时间看懂了网上的一段很有意思的代码,然后自己进行了一些修改,交上去结果超限!!!但是这种思路还是很值得学习的!!!
切记!PAT为了安全性不能使用gets()!

法一

思路大致为:
首先创建的是字符串数组,每个存储单元里面放的是一个字符串
每个扫描进来的字符做循环变量,如果遇到回车就终止循环,遇到空格就将计数器加一代表一个完整的单词,如果字符不是空格,则往对应的字符串里面追加该个字符,组成一个单词
最后根据单词计数器逆序输出,最后一位则不输出空格
for循环的过程可以看下图来体会一下
在这里插入图片描述

#include<iostream>
using namespace std;
int main() {
	freopen("1.txt", "r", stdin);
	string str[81];
	int counter = 0;
	for (char st; st = getchar(), st != '\n';st==' '?counter++:0){
		if (st != ' '){
			str[counter].insert(str[counter].end(), { st });
		} 
	}
	for (int i = counter ; i >= 0; i--){
		if(i){
			cout << str[i] << " ";
		}else{
			cout << str[i] << endl;
		}
	}	
	return 0;
}


法二

最后过的是老老实实的用了一个容器,拼成单词,遇到空格压入容器后,最后倒序输出

#include<iostream>
#include<string.h>
#include<vector>
using namespace std;
int main()
{
	vector<string> v;
	string str;
	getline(cin,str);
	string tmp="";
	for(int i=0;i<str.length();i++)
	{
		if(str[i]=='\n')
			break;
		if(str[i]!=' ')
			tmp += str[i];
		else
		{
			v.push_back(tmp);
			tmp="";
		}
	}
	v.push_back(tmp);
	for(int i=v.size()-1;i>=0;i--)
	{
		if(i!=0)
			cout<<v[i]<<" ";
		else
			cout<<v[i];
	}
	system("pause");
	return 0;
}

发布了13 篇原创文章 · 获赞 1 · 访问量 267

猜你喜欢

转载自blog.csdn.net/weixin_43849089/article/details/104482686