开始: 2022-01-13 09:00:00

2022年1月双周赛

结束: 2022-01-13 12:00:00
当前: 2025-0505-3131 13:51:00  类型:OI 状态:已经结束 

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;

}