2024PAT乙级春考B-2 真爱99 题型:字符串 20分

121 阅读4分钟

image.png 这道题我的思想是用substr()从左到右截取,求个和,再从右到左截取求个和,如果和%99都等于69,说明是真爱99 ,否则就不是。

从左向右截取:除了最后一位截取1位,剩下的都是2位一截取。

从右向左截取:除了第一位截取一位,剩下的每一位都截取2位。

我刚开始写的代码如下:

#include<iostream>
#include<vector>
#include<string>
#include<cstring>
#include<sstream>
using namespace std;
string str;
vector<string>v, v2;
int sum, sum2;
int flag1 = 0, flag2 = 0;
int no = 0;
int t1, t2;
int main()
{
    int  n; cin >> n;
    for (int i = 0; i < n; i++)
    {
        flag1 = 0; flag2 = 0; sum = 0; //每一轮重置
        sum2 = 0; v.clear(); v2.clear();
        t1 = 0, t2 = 0;
        string temp; cin >> temp;
        //从左向右截取每2位,不满2位的截取一位


        for (int i = 0; i < temp.size(); i++)
        {
            
            if (i == temp.size() - 1) {  //到最后的时候只截取一位
                //截取一位
                str = temp.substr(i, 1);
                v.push_back(str);
            }
            else   //第一次截取二位
            {
                str = temp.substr(i, 2);
                i++;
                v.push_back(str);
            }
        }



        // 验证从右往左走
// for (int i = 0; i < v.size(); i++)
// {
//     cout << v[i] << " ";
// }

       //进行相加
        for (int i = 0; i < v.size(); i++)
        {
            stringstream ss;
            int num = 0;
            ss << v[i];
            ss >> num;
            sum += num;
        }
        t1 = sum % 99;



 
        //    //第一位截取2位,最后一位截取一位
        for (int j = 0; j <= temp.size(); j++)
        {
            if (j == 0) //第一位截取一位
            {
                str = temp.substr(j, 1);
                v2.push_back(str);
            }


            else //截取二位
            {
                str = temp.substr(j, 2);
                j++;
                v2.push_back(str);
            }
        }

        //    // 验证从右往左走
        // for (int i = 0; i < v2.size(); i++)
        // {
        //     cout << v2[i] << " ";
        // }

        for (int i = 0; i < v2.size(); i++)
        {
            stringstream ss;
            int num = 0;
            ss << v2[i];
            ss >> num;
            sum2 += num;
        }
        t2 = sum2 % 99;


        if (t1 == t2)cout << "yes" << endl;
        else cout << "no" << endl;

    }
    return 0;
}

但是会有一个样例(第三个样例)过不去:

1234

这个时候从左往右应该是

1   23  4

从右向左也应该1是:

1 23  4

答案应该是“Yes",所以我们应该再加个条件:当 数组个数为偶数个的时候这个时候第一位和最后一位我们应该都只截取一位数字,中间部分截取两位数字:

AC代码如下:

#include<bits/stdc++.h>
using namespace std;
string str;
vector<string>v, v2;
int sum, sum2;
int flag1 = 0, flag2 = 0;
int no = 0;
int t1, t2;
int main()
{
    int  n; cin >> n;
    for (int i = 0; i < n; i++)
    {
        flag1 = 0; flag2 = 0; sum = 0; //每一轮重置
        sum2 = 0; v.clear(); v2.clear();
        t1 = 0, t2 = 0;
        string temp; cin >> temp;
        //从左向右截取每2位,不满2位的截取一位


        for (int i = 0; i < temp.size(); i++)
        {
            
            //当 数组个数为偶数个的时候这个时候第一位和最后一位我们应该都只截取一位数字,中间部分截取两位数字:
            if (i == temp.size() - 1||(temp.size()%2==0&&i==0)) { 
                //截取一位
                str = temp.substr(i, 1);
                v.push_back(str);
            }
            else   //第一次截取二位
            {
                str = temp.substr(i, 2);
                i++;
                v.push_back(str);
            }
        }



        // 验证从右往左走
// for (int i = 0; i < v.size(); i++)
// {
//     cout << v[i] << " ";
// }

       //进行相加
        for (int i = 0; i < v.size(); i++)
        {
            stringstream ss;
            int num = 0;
            ss << v[i];
            ss >> num;
            sum += num;
        }
        t1 = sum % 99;




        //     //第二部分 从右往左截取

        //    //第一位截取2位,最后一位截取一位
        for (int j = 0; j <= temp.size(); j++)
        {
            if (j == 0) //第一位截取一位
            {
                str = temp.substr(j, 1);
                v2.push_back(str);
            }


            else //截取二位
            {
                str = temp.substr(j, 2);
                j++;
                v2.push_back(str);
            }
        }

        //    // 验证从右往左走
        // for (int i = 0; i < v2.size(); i++)
        // {
        //     cout << v2[i] << " ";
        // }

        for (int i = 0; i < v2.size(); i++)
        {
            stringstream ss;
            int num = 0;
            ss << v2[i];
            ss >> num;
            sum2 += num;
        }
        t2 = sum2 % 99;


        if (t1 == t2)cout << "yes" << endl;
        else cout << "no" << endl;

    }
    return 0;
}

这是之后补题写的,我把从左向右拆位和从右向左拆位都封装起来了,更简略。而且当时现场的时候我没注意到,题目中说了偶数位的一定是真爱99,所以偶数位就没必要判断了,直接输出:yes即可,只用处理奇数位的数字。

#include<bits/stdc++.h>
using namespace std;

int right(string s)
{
	int sum=0;
	string temp;
	for (int i = 0; i < s.size()-1; i++)
	{
		if (i == 0)temp = s.substr(0, 1);
		else
		{
			temp = s.substr(i, 2);
			i++;
		}
		//cout << "temp: " << temp << endl;
		int num = stoi(temp);
		sum += num;
	}
	return sum % 99;
}
int left(string s)
{
	int sum = 0;
	string temp;
	for (int i = 0; i < s.size(); i++)
	{
		if (i == s.size())temp = s.substr(0, 1);
		else
		{
			temp = s.substr(i, 2);
			i++;
		}
		//cout << "temp: " << temp << endl;
		int num = stoi(temp);
		sum += num;
	}
	return sum % 99;
}
int main()
{
	int n; cin >> n;
	for (int i = 0; i < n; i++)
	{
		string s; cin >> s;

		if (s.size() % 2 == 0) {
			cout << "yes" << endl;
			//return 0;
		}
		else
	    {

			//从右向左
			int r1=right(s);
			//cout << "r1:" << r1 << endl;
			//从左向右
			int r2=left(s);
			//cout << "r2:" << r2 << endl;
		   
			if (r1 == r2)cout << "yes" << endl;
			else cout << "no" << endl;
		}
	}

	return 0;
}