作者:指针不指南吗
专栏:codeforces或许会很慢,但是不可以停下来
Problem - 1833A - Codeforces
题意 :把一个单词,分成若干连续的只含两个字符的字符串,判断两字符串的种类
Solution: 使用 strsub
截取字符串的两个字符,放在一个 STL 容器里面,判断容器大小
代码实现:
#include
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
string s;
cin>>s;
set<string> x;
for(int i=1;i<n;i++)
{
string a=s.substr(i-1,2);
x.insert(a);
}
cout<<x.size()<<endl;
}
return 0;
}
知识点:
substr(start, length)
返回一个从指定位置开始,并具有指定长度的子字符串。
a. start:必选。所需的子字符串的起始位置。字符串中第一个字符的索引为 0。
b. length:可选项。返回的子字符串中包含的字符数。
在集合(Set)中,元素是不允许重复的。每个元素在集合中只能出现一次。当你尝试向集合中添加一个已经存在的元素时,集合会忽略该操作,因为元素已经存在于集合中了。
而在映射(Map)中,元素是以键-值(key-value)对的形式存储的。在Map中,键是唯一的,但值可以重复。这意味着你可以使用相同的键存储不同的值,但对于给定的键,只能有一个与之关联的值,新值覆盖原值。
将元素放进 set 容器中,判断种类
Problem - 1833B - Codeforces
题意 :a数组是天气预报的气温,b数组是实际的气温(元素顺序是混乱的),已知实际与预报的相差不超过k度,求一组 每天以正确顺序排列的温度值
Solution: 排序排序排序,将两个数组sort 从小到大排序,然后按照 a 数组原本的序号,输出排完b的值
代码实现:
#include
using namespace std;
#define x first
#define y second
#define all(x) (x).begin(),(x).end()
int main()
{
int T;
cin>>T;
while(T--)
{
int n,m;
cin>>n>>m;
vector<pair<int,int> > a(n); //a没有指定其大小,导致后续的赋值操作会导致越界访问
for(int i=0;i<n;i++)
{
cin>>a[i].x; //a[i].x 表示a数组的值
a[i].y=i; //a[i].y 表示a数组的序号
}
sort(all(a));
vector<int> b(n),c(n); //b数组即题目中的b数组,c表示ans数组
for(int i=0;i<n;i++)
cin>>b[i];
sort(all(b));
for(int i=0;i<n;i++)
c[a[i].y]=b[i]; //按照 a中序号作为ans的下标,ans值就是b的值
for(int i=0;i<n;i++)
cout<<c[i]<<' '; //输出ans
cout<<endl;
}
return 0;
}
知识点:
sort 对pair 排序 ,默认对 first
进行升序排列 , 当first
相同时, 对second
进行升序排列,如有需求时,自己写一个cmp
实现对其别的要求的排序 。
vector 使用push
赋值,vector的大小自动更新;
但是上面代码中,我们先访问vector的下标,然后再对其赋值,不声明的话,默认vector大小是0,会导致后面访问越界。
Problem - C - Codeforces
题意:根据大小为n的原数组a,构建一个美丽数组 b , 美丽数组中的所有数字都大于零,并且要么都是偶数,要么都是奇数。并且 b i b_i bi 只能从 a i a_i ai 或者是 a i − a j a_i-a_j ai−aj 中选择,j 属于(1,n)。判断能否形成美丽数组。
我的 Solution:
美丽数组奇偶性的确定:模拟+找规律 发现 a[0] or a[0]-a[j]
,由这两个数决定
需要进行奇偶数的转换,如下,发现只需要只要奇数的最小值即可
奇数=偶数-奇数
偶数=奇数-奇数
遍历数组,如果在美丽数组奇数数组遇到偶数,则需要把偶数换成奇数,判断偶-min奇>0
,ture 则 YES
,否则NO
代码实现:
#include
using namespace std;
const int N=2*1e5+10;
int a[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int flag=0;
int n,t=INT_MAX;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
if(a[i]%2)
t=min(t,a[i]); //min奇数
}
if(a[0]%2) //奇数
{
for(int i=1;i<n;i++)
{
if(a[i]%2==0) //偶数
{
if((a[i]-t)<0)
{
puts("NO");
flag=1;
break;
}
}
}
}
if(a[0]%2==0&&(a[0]-t)<=0) //偶数
{
for(int i=1;i<n;i++)
{
if(a[i]%2)
{
if((a[i]-t)<=0)
{
puts("NO");
flag=1;
break;
}
}
}
}
if(a[0]%2==0&&(a[0]-t)>0)
{
for(int i=1;i<n;i++)
{
if(a[i]%2==0) //偶数
{
if((a[i]-t)<0)
{
puts("NO");
flag=1;
break;
}
}
}
}
if(!flag)
puts("YES");
}
return 0;
}
大佬 Solution:
直接找出a中的最小值,如果最小值为奇数,那么a中大于它的偶数都可以减去它成为奇数,所以一定可以;如果最小数为偶数,那么如果a中有奇数,则无解,否则有解。
代码实现:
#include
#define endl '\n'
#define fi first
#define se second
#define all(a) a.begin(), a.end()
#define pd push_back
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef pair<double, double> PDD;
const int N = 2e5 + 10, M = N * 2, INF = 0x3f3f3f3f;
int n, m;
int w[N];
inline void solve()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>w[i];
sort(w+1,w+n+1);
if(w[1]%2) cout<<"YES"<<endl;
else{
for(int i=1;i<=n;i++)
if(w[i]%2){
cout<<"NO"<<endl;
return ;
}
cout<<"YES"<<endl;
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int T;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
显然,大佬的代码逻辑性更强