A A A题:
题目大意:n个数中选出x个数,全部 & \& &一遍,请问最小为多少
做法:根据 & \& &的性质,按位与后只会变小,所以应该贪心,直接选整个数组。
注意特判
代码如下:
/*
coder:sunshine
school:njupt
*/
#include <bits/stdc++.h>
#define endl '\n' //交互题删掉
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin>>n;
int a[n];
for(int i=0;i<n;i++)
{
cin>>a[i];
}
int ans=a[0];
if(n==1)
{
cout<<ans<<endl;
return 0;
}else
{
for(int i=1;i<n;i++)
{
ans=ans&a[i];
}
}
cout<<ans<<endl;
return 0;
}
B B B题:
题目大意:初始伤害值为2点,有m次攻击机会,每次攻击从左往右所有小兵,最后打英雄,如果恰好击杀一个小兵,则伤害+1,问m次后对英雄造成了多少伤害。
做法:模拟遍历就行
代码如下:
/*
coder:sunshine
school:njupt
*/
#include <bits/stdc++.h>
#define endl '\n' //交互题删掉
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int N = 8;
int a[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
int dmg = 2;
int ans = 0;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
while (m--)
{
for (auto &c : a)
{
if (c - dmg == 0)
{
c -= dmg;
dmg++;
}
else
{
c -= dmg;
}
}
ans += dmg;
}
cout << ans << endl;
return 0;
}
C C C题:
题目大意:两方有n只队,任意挑选 b a t t l e battle battle,获胜条件是哪只的大爹数量多,求平局,胜局,负局数量。
做法:全排列一下,然后循环判断一下
代码如下:
/*
coder:sunshine
school:njupt
*/
#include <bits/stdc++.h>
#define endl '\n' //交互题删掉
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int N=5e6+3;
ll n,m,sx,sy,sz,a[N],b[N];
int main()
{
cin>>n;ll p=1,w=0;
for(int i=1;i<=n;i++)p=p*i;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)cin>>b[i];
while(w<p)
{
w++;ll x=0,y=0;
next_permutation(a+1,a+n+1);
for(int i=1;i<=n;i++)
{
if(a[i]>b[i])x++;
if(a[i]<b[i])y++;
}
if(x>y)sx++;
if(x<y)sy++;
if(x==y)sz++;
}
cout<<sx<<" "<<sy<<" "<<sz;
return 0;
}
D D D题:
题目大意:有一个环,上面有n位,有k种花费的颜料给环上色,要求是不能出现连续三次相同的颜色环,求花费最小。
做法:是一道贪心思维题。设花费为 w 1 , w 2 , w 3 , … w_1,w_2,w_3,\ldots w1,w2,w3,…,求花费最小,即以 w 1 , w 1 , w 2 w_1,w_1,w_2 w1,w1,w2的顺序依次上色,到最后要特判一下,如果刚好 % 3 = = 0 \%3==0 %3==0,不需要改动,如果除不尽的话,就要 将一个 w 1 改为 w 2 ,防止出现 w 1 , w 1 , w 1 的组合 将一个w_1改为w_2,防止出现w_1,w_1,w_1的组合 将一个w1改为w2,防止出现w1,w1,w1的组合。
代码如下:
/*
coder:sunshine
school:njupt
*/
#include <bits/stdc++.h>
#define endl '\n' //交互题删掉
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int N=5;
int w[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,k;
cin>>n>>k;
for(int i=1;i<=k;i++)
{
cin>>w[i];
}
sort(w+1,w+k+1);
if(k==1)
{
cout<<"Ginger666"<<endl;
}else
{
ll ans=0;
for(int i=1;i<=n;i++)
{
if(i%3) ans+=w[1];
else ans+=w[2];
}
if(n%3)
{
ans-=w[1];
ans+=w[2];
}
cout<<ans<<endl;
}
return 0;
}
先补了昨天小白月赛63的 E E E题
E E E题:
题目大意:求n个数的全排列中 ( 区 间 m a x = n , 区 间 m i n = 1 ) (区间_{max}=n,区间_{min}=1) (区间max=n,区间min=1)的子区间数量,对998244353取模。
即求 ∑ p ∑ i = 1 n ∑ j = i n [ m a x k = i j p k = n ] [ m i n k = i j p k = 1 ] \sum_{p} \sum_{i=1}^{n} \sum_{j=i}^{n}[max_{k=i}^{j} p_k=n][min_{k=i}^{j} p_k=1] ∑p∑i=1n∑j=in[maxk=ijpk=n][mink=ijpk=1]
做法:可以用数学方法做:从左往右选 i i i的位置,再从 i i i的右边到最后选 j j j的位置,最左边到 i i i的个数乘以 j j j到最右边的个数即是答案,注意要 × 2 ×2 ×2,也要乘 ( n − 2 ) ! (n-2)! (n−2)!,因为 n 和 1 n和1 n和1的位置可以互换,并且剩下n-2个数也可以随便排列。
即
a
n
s
=
2
(
n
−
2
)
!
∑
i
=
1
n
∑
j
=
i
+
1
n
i
(
n
−
j
+
1
)
%
998244533
ans=2(n-2)!\sum_{i=1}^{n} {\sum_{j=i+1}^{n} {i(n-j+1)}}\%998244533
ans=2(n−2)!i=1∑nj=i+1∑ni(n−j+1)%998244533
显然
n
=
1
e
6
n=1e6
n=1e6时,上面这个式子时间复杂度为
O
(
n
2
)
O(n^2)
O(n2),肯定超时了,所以要对式子进行优化,优化到
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn),
O
(
n
)
O(n)
O(n)最好。
可以对中间这个式子优化:
∑
i
=
1
n
∑
j
=
i
+
1
n
i
(
n
−
j
+
1
)
=
∑
i
=
1
n
(
∑
j
=
i
+
1
n
i
⋅
n
+
∑
j
=
i
+
1
n
−
i
j
+
∑
j
=
i
+
1
n
i
)
=
∑
i
=
1
n
[
(
n
−
i
)
⋅
(
i
n
+
i
)
−
i
⋅
∑
j
=
i
+
1
j
j
]
=
∑
i
=
1
n
[
i
(
n
−
i
)
(
n
+
1
)
−
i
(
i
+
1
)
+
n
2
⋅
(
n
−
i
)
]
\sum_{i=1}^{n} {\sum_{j=i+1}^{n} {i(n-j+1)}}\\ =\sum_{i=1}^{n} {(\sum_{j=i+1}^{n} {i\cdot n}+\sum_{j=i+1}^{n} {-ij}+\sum_{j=i+1}^{n} {i})}\\ =\sum_{i=1}^{n} {[(n-i)\cdot (in+i)-i\cdot \sum_{j=i+1}^{j} {j}]}\\ =\sum_{i=1}^{n} {[i(n-i)(n+1)-i\frac{(i+1)+n} {2}\cdot (n-i)]}
i=1∑nj=i+1∑ni(n−j+1)=i=1∑n(j=i+1∑ni⋅n+j=i+1∑n−ij+j=i+1∑ni)=i=1∑n[(n−i)⋅(in+i)−i⋅j=i+1∑jj]=i=1∑n[i(n−i)(n+1)−i2(i+1)+n⋅(n−i)]
就可以优化成
O
(
n
)
O(n)
O(n)的时间复杂度
代码如下:
/*
coder:sunshine
school:njupt
*/
#include <bits/stdc++.h>
#define endl '\n' //交互题删掉
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const ll mod = 998244353;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
if (n == 1)
{
cout << 1 << endl;
}
else
{
ll ans = 0;
for (ll i = 1; i <= n; i++)
{
ans = (ans + (n - i) * (n * i + i) - (ll)i * (i + 1 + n) * (n - i) / 2ll) % mod;
}
for (ll i = 1; i <= n - 2; i++)
{
ans = ans * (ll)i % mod;
}
ans = ans * 2ll % mod;
cout << ans << endl;
}
return 0;
}