这是一道很有趣味的题目,逆向了图中找舍友的过程。
我们可以看出来第一个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
类型,可以使用 显式类型转换 或 隐式类型转换。
显式类型转换
-
C风格的强制转换: 使用
(int)
将一个值转换为int
类型。double x = 3.14; int y = (int)x; // 将 double 类型的 x 强制转换为 int 类型
-
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()–返回一个用于比较元素间的值的函数