2022年1月双周赛
T1-反转
看到这道题可能大家会想到曾经学过的三位数反转,从而把以前的方法套用进来。
但这道题是一道比较简单的题,理解题意后,我们可以用更简单的方法去处理它:读入这个字符串,倒序输出即可。
具体实现上,由于保证了数据范围,也保证了只有一位小数,我们可以直接读入字符串并翻转,也可以直接读入四个数字字符,后一种方法代码如下(scanf引号中的 ‘ . ’ 表示读入时忽略该符号):
#include<bits/stdc++.h>
using namespace std;
char a, b, c, d;
int main()
{
scanf("%c%c%c.%c", &a, &b, &c, &d);
printf("%c.%c%c%c", d, c, b, a);
return 0;
}
T2-吃桃子
一道简单的循环基础题,每次+1后再*2即可,注意循环次数是n-1次不是n次。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,s = 1;
cin>>n;
for(int i = 1;i < n;i++)
{
s++;
s *= 2;
}
cout<<s<<endl;
return 0;
}
T3-单词分类
这道题数据范围较小,可以考虑比较暴力的做法。
一个字符串相当于一个字符数组,我们可以利用sort在这个字符串的内部进行排序,即让字符串内的字符顺序变成从小到大。例如字符串 “ JZACB ” 排序后变成 “ ABCJZ ” 。
容易发现,同一类的单词,排序后会变得一模一样(因为每种字母数目相等),于是问题转化成了求互不相同的字符串个数。
我们再对字符串数组进行排序,即对所有字符串按照字典序排序,排序后相同的字符串显然是挨在一起的。由于数组有序,这个问题就类似于以前做过的,在升序数组中找不同的数字有多少个的问题,处理方式比较简单,详见代码。
#include<bits/stdc++.h>
using namespace std;
int n,sum;
string s[100000];
char t;
int main()
{
cin>>n;
for (int i=0;i<n;i++)
{
cin>>s[i];
sort(s[i].begin(),s[i].end());//每一个字符串内部进行排序,s[i].begin()表示指向字符串开头的指针,s[i].end()指向结尾,这句代码意思是对begin到end之间的字符进行排序
}
sort(s,s+n); //再将所有的字符串排序一次
for (int i=0;i<n;i++) if (i==0||s[i-1]!=s[i]) sum++; //统计有多少个字符串互不相同
cout<<sum;
return 0;
}
T4-斐波那契数列
这个问题可以分为三步:
第一步,求斐波那契数列的第n项。
第二步,答案对2^{31}取模。
第三步,分解质因数。
第一步比较简单,不再细说。
第二步看似简单,但我们知道,c++中int类型存在溢出的问题。第n项可能会很大,取模是为了防止它超出int的表示范围。如果我们把第n项算出来之后再取模,在取模之前这个数可能已经溢出,变成负数了,这样我们再取模,得到的答案是不正确的。
提示中写了这样一个定理:(a + b) % p = (a % p + b % p) % p 。利用这个原理,我们就可以边计算第n项边取模,代码如下:
a[i]=(a[i-1]%p+a[i-2]%p)%p;
还需注意,2^{31}超出了int范围,需要用long long存储。
然后考虑第三步分解质因数,这时很多同学可能会纠结于判断除数是否是质数的问题,但其实这个问题并不需要过多纠结。
我们只需从2开始从小到大枚举比这个数小的数,由于是因数,和判断质数时一样,枚举到i*i<=s
即可,枚举到s会超时。
一旦遇到求余等于0的数,便用一个while循环不断除以这个数,直到除不尽为止。
由于我们是从小到大枚举,每次枚举到的因数一定是质数。因为不是质数的数一定有比它小的质因数,这些质因数已经被我们除掉了。
退出循环后,需注意还剩分解之后得到的数没有输出。
最后,请大家注意乘号的输出,不能多输或少输。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int a[50],n,s;
const long long p=pow(2,31);
int main()
{
a[1]=1;
a[2]=1;
cin>>n;
for(int i=3;i<=n;i++) a[i]=(a[i-1]%p+a[i-2]%p)%p;
s=a[n];
printf("%d=",s);
for(int i=2;i*i<=s;i++)
{
while(s%i==0&&s!=i)//注意s!=i这个条件,否则n=6时会出错
{
printf("%d*",i);
s/=i;
}
}
printf("%d",s);
return 0;
}