*1:签到题-5
*2:区间并集
*3:特殊的01串
*4:公因数-2
*5:WSAD
*6:数组的贡献值
描述
嘉庚学院开展了为期两周的线上教学活动,其中出勤是一个很重要的指标。
每次有 n 个同学应该来参加线上课程,他们都有自己独特的学号来进行签到。
但总有一个同学睡过了头也就是他没有签到,要接受爆照的处罚(奖励),你能帮老师找出是谁这么幸运么?
输入
只有一组案例。
第一行是一个正整数 n,表示本次课程应该有 n 个同学来参与。(2 <= n <= 1e5)
第二行是 n 个互不相同的正整数 xi,分别表示这 n 个同学独特的学号。(1 <= xi <= 1e9)
第三行是 n - 1 个互不相同的正整数,表示老师给出的已经签到的 n - 1 个同学的学号。(保证是这节课应该来的同学的学号)
输出
输出一个正整数,表示没有签到同学的学号,然后换行。
样例输入
4
2 3 4 8
8 3 4
样例输出
2
HINT
老师给出的学号和应签到的学号都不一定有序。
来源
20-21(2)第0次线上赛
解:
1、(最简单的)(来自大佬涂涂)第一次输入的和-第二次输入的和。
2、(来自IST大佬)map容器 key-value学号不重复>set>s. erase>输出
(太难不细说)(俺不会-理直气壮)
3、两个一维数组进行sort排序,第一个对不上号的就是没到的(下面代码)。
#include
#include
//algorithm-sort
using namespace std;
int main()
{
int n;
cin>>n;
int *a=new int[n]();
int *b=new int[n-1]();
for(int i=0;i<n;i++)
{
cin>>a[i];
}
sort(a,a+n-1);
for(int i=0;i<n-1;i++)
{
cin>>b[i];
}
sort(b,b+n-2);
bool sc=0;
for(int i=0;i<n-1;i++)
{
if(sc==0)
{
if(a[i]!=b[i])
{
cout<<a[i]<<endl;
sc=1;
break;
}
}
}
if(sc==0) cout<<a[n-1]<<endl;
delete []a;
delete []b;
return 0;
}
描述
存在 n 个区间:a1、a2、…… 、an。
求 a1 ∪ a2 ∪ a3 ∪ …… ∪ an。
输入
只有一组案例。
第一行正整数 n 表示区间的个数。(1 <= n <= 1e5)
然后是 n 行,每行包含两个正整数 L 和 R,分别表示一个区间左右端点,即 [ L,R ]。(0 <= L <= R <= 1e10)
输出
根据左端点的大小,从小到大输出取并集后的每个区间。
每个区间的左端点和右端点之间用空格隔开,每次输出以后都要换行。
样例输入
6
1 2
1 4
8 10
8 9
5 6
6 7
样例输出
1 4
5 7
8 10
HINT
[1,2] 区间和 [1,4] 区间取并集后变为 [1,4]
[5,6] 区间和 [6,7] 区间取并集后变为 [5,7]
[8,9] 区间和 [8,10] 区间取并集后变为 [8,10]
来源
20-21(2)第0次线上赛
解:
1、结构体存储每一次输入的L、R(左右端),然后sort排序,排序规则看compare,然后记录第一个L、R为l、r,后面有L大于记录的r时输出存储的l、r,存储新的L、R,如果后面的L不大于记录的r则合并合集,取俩合集(存储的l、r和该次的L、R)中最小的左端为l和最大的右端为r。(下面代码)
#include
#include
using namespace std;
typedef long long int ll;
struct qj
{
ll L;
ll R;
};
qj s[100005];
bool compare(qj a,qj b)
{
if(a.L==b.L)
{
return a.R<b.R;
}
return a.L<b.L;
}
int main()
{
ll n;
cin>>n;
for(ll i=1;i<=n;i++)
{
cin>>s[i].L>>s[i].R;
}
//cout<<"opening"<
sort(s,s+n+1,compare);
ll l=0,r=0;
for(ll i=1;i<=n;i++)
{
if(i==1)
{
l=s[i].L;
r=s[i].R;
}
else
{
if(s[i].L>r)
{
cout<<l<<" "<<r<<endl;
l=s[i].L;
r=s[i].R;
}
else
{
if(s[i].R>r)
{
r=s[i].R;
}
}
}
}
cout<<l<<" "<<r<<endl;
return 0;
}
描述
我们定义一个字符串是特殊的01串:
1.空串是特殊的01串。
2.仅由字符 0 和 1 构成且任意两个相邻的字符不都为 1。
现在请你构造一个长度为 n 的特殊的01串,请问你可以构造多少个?
输入
第一行是一个正整数 T 代表测试案例的数量。(1 <= T <= 1e5)
每组案例是一个整数 n,代表构造字符串的长度。(0 <= n <= 1e6)
输出
针对每组案例,输出你可以构造多少个,然后换行。
由于答案可能很大,所以你只需要输出它对 998244353 取模以后的结果。
样例输入
1
3
样例输出
5
HINT
长度为 3 的特殊的01串可以是 100 010 001 101 000。
来源
20-21(2)第0次线上赛
解:
1、找规律,数组存储(下面代码)。
#include
#include
#define mod 998244353
using namespace std;
int ans[1000005];
int main()
{
memset(ans,0,sizeof(ans));
ans[0]=1;ans[1]=2;ans[2]=3;ans[3]=5;
for(int i=4;i<=1000005;i++)
{
ans[i]=(ans[i-1]+ans[i-2])%mod;
}
int T;
cin>>T;
for(int f=1;f<=T;f++)
{
int n;
cin>>n;
cout<<ans[n]<<endl;
}
return 0;
}
描述
有 n 个数字,求它们的公共质因数。
输入
只有一组案例。
第一行是一个正整数 n 代表数字的个数。(1 <= n <= 1e5)
然后是 n 个正整数,对于每一个正整数 x 都有 1 <= x <= 1e5。
输出
按从小到大的顺序依次输出这 n 个数字的公共质因数,每两个数字之间用空格隔开,最后一个数字后面没有空格。
如果它们没有公共质因数则输出 No。
最后换行。
样例输入
3
6 12 18
样例输出
2 3
HINT
来源
20-21(2)第0次线上赛
解:
1.筛法筛出1e5以下的素数,排序所给的数字以后循环判断每个素数是否是公因数(下面代码)。
2.(不需要筛法)(来自CST大佬)排序从小到大——拿a[0]找小于等于它的质数——得到质数判断是不是公因数——是——输出。
#include
#include
using namespace std;
const int N=100005;
int p[N];
int prime[N];
int cnt=0;
void xxs()
{
for (int i = 2; i <= N; i++)
{
if(p[i] == 0)
{
p[i]=i;
prime[cnt++]=i;
}
for (int j = 0;j<cnt;j++)
{
if (prime[j]>p[i]||prime[j]*i>N)
{
break;
}
p[prime[j]*i]=prime[j];
}
}
}
int main()
{
bool sc=0;
int sz[100005];
memset(sz,0,sizeof(sz));
xxs();
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>sz[i];
}
for(int i=0;i<cnt;i++)
{
for(int j=1;j<=n;j++)
{
if(sz[j]%prime[i]!=0) break;
else if(j==n)
{
if(sc==0)
{
cout<<prime[i];
sc=1;
}
else cout<<" "<<prime[i];
}
}
}
if(sc==0) cout<<"No";
cout<<endl;
return 0;
}
描述
罗少在玩一个游戏,用 W S A D 分别控制角色进行 上 下 左 右 移动,我们可以把地图看作一个二维平面,罗少初始站在原点,现在他操作了 n 次,请你输出他的位置。
输入
第一行是一个正整数 n 代表测试案例的数量。(1 <= n <= 100)
每组案例是一个仅包含字符WSAD的字符串 t 代表罗少的操作。(1 <= length(t) <= 100)
输出
针对每组案例,输出罗少操作以后所在位置的横纵坐标,两者之间用空格隔开,然后换行。
样例输入
2
WWW
SSD
样例输出
0 3
1 -2
HINT
来源
20-21(2)第0次线上赛
解:
1、循环判断字符串每一个字符(下面代码)。
2、(来自CST大佬)使用count计算WASD的个数,直接计算。
#include
#include
#include
using namespace std;
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
int x=0,y=0;
string s;
cin>>s;
int lg=s.size();
for(int j=0;j<=lg;j++)
{
if(s[j]=='W') y++;
if(s[j]=='S') y--;
if(s[j]=='A') x--;
if(s[j]=='D') x++;
}
cout<<x<<" "<<y<<endl;
}
return 0;
}
给定一个长度为 n 的数组,定义数组的贡献值为数组中 每个数首次出现的位置 * 每个数出现的次数 之和(相同的数字只计算一次)。
例如:1 2 2 3 1,数字 1 首次出现的位置是 1,总共出现了 2 次,所以提供 1 * 2 = 2 的贡献值,数字 2 是 2 * 2 = 4,数字 3 是 4 * 1 = 4,因此这个数组的贡献值为 2 + 4 + 4 = 10。
但很显然这样是难不倒罗少的,所以附加了一个条件,你可以任意改变数组中数的位置,问改变后数组最大的贡献值是多少?
输入
第一行是一个正整数 T 代表测试案例的数量。(1 <= T <= 10)
每组案例包含一个正整数 n ,代表数组的长度。(1 <= n <= 100000)
然后是 n 个整数 ai。(|ai| <= 10000)
输出
针对每组案例,输出改变数字位置后可以得到的最大数组贡献值,然后换行。
样例输入
2
4
1 2 1 2
4
1 1 2 2
样例输出
8
8
HINT
注意:数组也可以不发生改变。
对于样例1:1 2 1 2
改变前数组的贡献值为 1 * 2 + 2 * 2 = 6
你可以把他改为 1 1 2 2 或者 2 2 1 1 得到更大的数组的贡献值 8。
来源
20-21(2)第0次线上赛
解:
无(太难了QWQ)