L1-027 出租 L1-025 正整数A+B L1-020 帅到没朋友PTA 最详细解析 刷题笔记心得2024-4-14



这是一道很有趣味的题目,逆向了图中找舍友的过程。

我们可以看出来第一个arr数组他是手机号字符串的所有数字字符,但不重复,且必然从大到小。

第二个index数组对应着 手机号字符串是对应arr数组的每个下标。
而且输出格式必须严格按照题目要求,这里建议直接复制题目,否则可能少打空格。
 

#include<bits/stdc++.h>
#include<vector>
#include<queue>
using namespace std;
const int N=10; 
bool st[N];int a[N];vector<int > V;
int main()
{
	string str;
	cin>>str;int j=0;
	priority_queue<int> heap;
	for(int i=0;i<str.size();i++)
	{
		int t=str[i]-'0';
		if(!st[t])
		{
			heap.push(t);
			st[t]=true;
		}
	}
	
	while (!heap.empty())
	{
        int x = heap.top();
        a[j]=x;
        j++;
        heap.pop();  
    }
    
	//for(auto p:a) cout<<p<<" ";
	//cout<<j<<" ";
	

	for(int i=0;i<str.size();i++)
	{
		for(int k=0;k<=j-1;k++)
		{
			if(str[i]-'0'==a[k])
			{
				V.push_back(k);
				break;
			}
		}
	}
	//for(int i=0;i<V.size();i++) cout<<V[i]<<" ";
	cout<<"int[] arr = new int[]{";
	for(int i=0;i<=j-1;i++)
	{
		if(i!=j-1)
			cout<<a[i]<<",";
		else
			cout<<a[i];
	}
	cout<<"};\n";
	
	cout<<"int[] index = new int[]{";
	for(int i=0;i<V.size();i++)
	{
		if(i!=V.size()-1)
			cout<<V[i]<<",";
		else
			cout<<V[i];
	}
	cout<<"};\n";
	return 0;
}


这道题做出来我是很有成就感的,虽然有两分测试点没有过。可能是有一些特例,以后一定补上。
这道题属于模拟类型。模拟题目给的情况变成算法。


这道题我学会了两个函数,可以将字符串转变成double和int类型。

在 C++ 中,要将字符串 "22. 18" 转换为实际的数值,你可以使用 std::stod 函数来将字符串转换为 double 类型,或使用 std::stoi 函数来将字符串转换为 int 类型。不过,你提到的字符串 "22. 18" 中包含一个空格,这会导致直接使用转换函数时出现错误,因为空格并不是一个有效的数字部分。

因此,你需要先去除字符串中的空格,然后再进行转换。下面是一个示例代码,展示了如何将字符串 "22. 18" 转换为实际的数值:

#include <iostream>
#include <string>
#include <algorithm>  // 包含 std::remove_if
#include <cctype>  // 包含 isspace

int main() {
    // 给定的字符串
    std::string str = "22. 18";

    // 去除字符串中的空格
    str.erase(std::remove_if(str.begin(), str.end(), ::isspace), str.end());

    // 将字符串转换为 double 类型
    double value = std::stod(str);

    // 输出转换后的值
    std::cout << "Converted value: " << value << std::endl;

    return 0;
}

在这个代码示例中:

  • 给定的字符串 str"22. 18"
  • 使用 str.erase 结合 std::remove_if::isspace 来去除字符串中的空格。
  • 使用 std::stod 函数将去除空格后的字符串转换为 double 类型。
  • 最后,输出转换后的数值 value

通过这种方式,你可以将字符串 "22. 18" 转换为实际的数值。

转化int和double类型

在 C++ 中,要将一个变量转换为 int 类型,可以使用 显式类型转换隐式类型转换

显式类型转换

  1. C风格的强制转换: 使用 (int) 将一个值转换为 int 类型。

    double x = 3.14; int y = (int)x; // 将 double 类型的 x 强制转换为 int 类型

  2. C++风格的强制转换: 使用 static_cast<int> 将一个值转换为 int 类型。

    double x = 3.14; int y = static_cast<int>(x); // 将 double 类型的 x 强制转换为 int 类型

两者的效果相同,但 static_cast 是 C++ 标准推荐的风格,因为它更明确,更容易阅读和理解。

隐式类型转换

如果你将一个非 int 类型的值赋给一个 int 类型的变量,C++ 会自动执行隐式转换。这可能导致数据的截断或丢失。

double x = 3.14; int y = x; // 隐式转换,double 类型的 x 被转换为 int 类型的 y

显式类型转换通常更安全,因为它让代码更清晰地表明开发者的意图。如果你希望进行转换,通常建议使用显式类型转换。


 

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

int main()
{
    string str;
    getline(cin,str);
    int ii=str.find(' ');
    string str1=str.substr(0,ii);
    string str2=str.substr(ii+1,str.size());
    //cout<<str1<<endl<<str2;
    
    bool flag_1=true,flag_2=true;    bool flag_stod=false;
    
    for(int i=0;i<str1.size();i++)
    {
        if(str1[i]>=48&&str1[i]<=57 ||str1[i]==46 )
        {
            if(str1[i]==46&&i+1==str1.size())
            {
                flag_1=false;
            }
            else if(str1[i]==46)
            {
                flag_stod=true;
            }
            continue;
        }
        else
            flag_1=false;
    }

    //使用 std::stod 函数来将字符串转换为 double 类型
    for(int i=0;i<str2.size();i++)
    {
        if(str2[i]>=48&&str2[i]<=57 || str1[i]==46)
        {
            if(str2[i]==46&&i+1==str2.size())
            {
                flag_2=false;
            }
            if(str2[i]==46)
            {
                flag_stod=true;
            }
            continue;
        }
        else
            flag_2=false;
    }
    
    if(flag_1==false)
    {
        cout<<"? + ";
    }
    else
    {
        cout<<str1<<" + ";
    }
    
    if( flag_2==false)
        cout<<"? =";
    else
    {
        cout<<str2<<" =";
    }
    if(flag_1==false||flag_2==false)
        cout<<" ?";
    else if(flag_stod)
        cout<<" "<<stod(str1)+stod(str2);
    else if(!flag_stod)
        cout<<" "<<stoi(str1)+stoi(str2);
    return 0;
}





又是一道很有趣味性的题目
看到这些“没有朋友的人可以是根本没安装“朋友圈”,也可以是只有自己一个人在朋友圈的人。虽然有个别自恋狂会自己把自己反复加进朋友圈,但题目保证所有K超过1的朋友圈里都至少有2个不同的人”“ID间用1个空格分隔,行的首尾不得有多余空格。如果没有人太帅,则输出No one is handsome。”我人都麻了,PTA这么搞。
我自己用模拟法就得了10分,样例过了,剩下10分超时了,俺这村里来的用数组加bool数组模拟,城里的都用上set了。

#include<bits/stdc++.h>
using namespace std;
const int N1=1000010;
int N,K,id[N1];
bool st[N1];
int main()
{
	cin>>N;
	int i=0;
	while(N--)
	{
		int k;
		cin>>k;
		if(k==1)
			continue;
		while(k--)
		{
			int w;
			cin>>w;
			id[i++]=w;
		}		
	}
	int p;
	cin>>p;
	bool flag_1=true;
	while(p--)
	{
		int w1;
		cin>>w1;
		bool flag=false;
		for(int j=0;j<i;j++)
		{	
			if(w1==id[j])
			{
				flag=true;
				break;
			}			
				
		}	
		if(!flag&&!st[w1]&&p!=1) 
		{
			cout << setw(5) << setfill('0') << w1<<" ";
			flag_1=false;st[w1]=true;
		}
		if(!flag&&!st[w1]) 
		{
			cout << setw(5) << setfill('0') << w1;
			flag_1=false;st[w1]=true;
		}
	}
	if(flag_1) cout<<"No one is handsome";

	return 0;
}




看网上大佬的题解:

 

1. 利用set容器( 有自带的查找函数find()  ),用s存储朋友圈id,s1存储要输出的id

2.朋友圈id输入分为两种情况,一种是2人以上,另一种是1个人;

 单个人不加入set,因为查询到他时,如果其他朋友圈id(也就是容器s)都没有查询到此id,并且已输出的id中也没有重复的此id(即if (s.find(id) == s.end() && s1.find(id) == s1.end())),那么他直接为 帅到没朋友 可以输出 【题中说:没有朋友的人也可以是只有自己一个人在朋友圈的人】
 这道题需要注意防止自恋狂多次加入朋友圈,即多次朋友圈个数为1,且为同一个人,而且,多次朋友圈为自己一个人的这个人如果出现在了其他人的朋友圈中,那么这个人不能说没朋友。
 3.输出:朋友圈id(s)和已输出的id(s1)中都没有你输入的待查的id,这就保证了同一个人可以被查询多次,但只输出一次



 

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

int main()
{
	int n;
	cin>>n;
	int k;
	int id;
	int m;
	int num=0;
	set<int> s,s1;
	for(int i=0;i<n;i++)
	{
		cin>>k;
		if(k>=2)
		{
			for(int j=0;j<k;j++)
			{
				cin>>id;
				s.insert(id);
			}
		}
		else
			cin>>id;
	}
	cin>>m;
	for(int i=0;i<m;i++)
	{
		cin>>id;
		if(s.find(id)==s.end()&&s1.find(id)==s1.end())
		{
			if(num!=0)
			{
				cout<<' ';
				
			}
			s1.insert(id);
			cout<<setw(5)<<setfill('0')<<id;
			num++;
		}
	}
	if(num==0)
		cout << "No one is handsome";
	return 0;
}



学会了这两个函数:

 

std::setw(int n)
作用:设置字段宽度,用于指定下一个输出项的最小字符数。

用法示例:

#include <iomanip>
std::cout << std::setw(10) << 42 << std::endl; // 输出:        42
std::setfill(char c)

std::setfill(char c)
作用:设置填充字符,用于填充字段的空白部分。

用法示例:

#include <iomanip>
std::cout << std::setfill('*') << std::setw(10) << 42 << std::endl; // 输出:********42


 

C++中set用法:
begin()–返回指向第一个元素的迭代器

clear()–清除所有元素

count()–返回某个值元素的个数

empty()–如果集合为空,返回true

end()–返回指向最后一个元素的迭代器

equal_range()–返回集合中与给定值相等的上下限的两个迭代器

erase()–删除集合中的元素

find()–返回一个指向被查找到元素的迭代器

get_allocator()–返回集合的分配器

insert()–在集合中插入元素

lower_bound()–返回指向大于(或等于)某值的第一个元素的迭代器

key_comp()–返回一个用于元素间值比较的函数

max_size()–返回集合能容纳的元素的最大限值

rbegin()–返回指向集合中最后一个元素的反向迭代器

rend()–返回指向集合中第一个元素的反向迭代器

size()–集合中元素的数目

swap()–交换两个集合变量

upper_bound()–返回大于某个值元素的迭代器

value_comp()–返回一个用于比较元素间的值的函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值