元宵节快乐
#include <iostream>
using namespace std;
int main()
{
cout<<"Today AK!"<<'\n';
return 0;
}
猜灯谜
#include <bits/stdc++.h>
using namespace std;
int arr[100010],n;
int main()
{
ios::sync_with_stdio(false),cin.tie(0);
cin>>n;
for(int i=0;i<n;i++) cin>>arr[i];
for(int i=0;i<n;i++) {
cout<<(arr[(i-1+n)%n]+arr[(i+1+n)%n])<<' ';
}
return 0;
}
数学奇才
不难发现对于一个长度为 n 的数组,在不超过 n 次操作下一定能将所有数变为正数,全部求和即可
#include <bits/stdc++.h>
using namespace std;
int arr[100010],n;
typedef long long ll;
int main()
{
ios::sync_with_stdio(false),cin.tie(0);
cin>>n;
ll sum=0;
for(int i=1;i<=n;i++) {
cin>>arr[i];
sum+=abs(arr[i]);
}
cout<<sum<<'\n';
return 0;
}
你不干?有的是帕鲁干!
设一个任意奇数 x,则两个连续奇数的平方差可以表示为 x 2 − ( x − 2 ) 2 x^2-(x-2)^2 x2−(x−2)2,化简即可发现这个数一定是 8 的倍数,最后记得特判0的情况
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ios::sync_with_stdio(false),cin.tie(0);
int t;
cin>>t;
while(t--) {
ll x;
cin>>x;
ll y=(x/4)+1;
if(x%4==0&&y%2&&y-2>0) cout<<"Yes"<<'\n'<<(y-2)<<' '<<(y)<<'\n';
else cout<<"No"<<'\n';
}
return 0;
}
等腰三角形
将两个数组排序之后,用双指针做,若 A ∗ 2 ≥ B A*2 ≥ B A∗2≥B 那么答案加一。
#include <bits/stdc++.h>
using namespace std;
int arr[200010],brr[200010];
int main()
{
ios::sync_with_stdio(false),cin.tie(0);
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>arr[i];
for(int i=1;i<=n;i++) cin>>brr[i];
sort(arr+1,arr+n+1),sort(brr+1,brr+n+1);
int pa=n,pb=n,ans=0;
while(pa&&pb) {
if(arr[pa]*2>brr[pb]) {
ans++,pa--,pb--;
} else {
pb--;
}
}
cout<<ans<<'\n';
return 0;
}
// 1 2 3 4
// 2 2 3 4
计算方程
计算
l
o
g
k
x
log_kx
logkx的方法:使用log函数,计算double res = log(x)/log(k)
,res 的值就是所求结果。
二分+库函数
#include <bits/stdc++.h>
using namespace std;
int k,m;
bool check(double x)
{
return sqrt(x)+(int)(log(x)/log(k))-m>0;
}
int main()
{
int t;
cin>>t;
while(t--) {
cin>>k>>m;
int l=1,r=1e9;
while(l<r) {
int mid=l+r>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
cout<<r<<'\n';
}
return 0;
}
谁是帕鲁?
题目要求在给定区间中找出满足封闭图形个数等于 k 的数的数量,考虑用数位dp来解决。
在读入数据之前,我们提前初始化数组dp,使用dp[i][j]
来表示一个 i 位的数字中封闭图形个数为 j 的方案数,由定义可以得到状态转移方程:dp[i][j] = dp[i - 1][j - number[1~9]]
,即 dp[i][j] 就等于当第 &j& 位数字为
u
(
1
≤
u
≤
9
)
u (1≤u≤9)
u(1≤u≤9) 时,前
i
−
1
i-1
i−1 位数字中封闭图形个数为 j - number[u]
的方案数之和。
对于任意一个数字
x
x
x,我们可以将其表示为
A
B
C
D
E
F
.
.
.
ABCDEF...
ABCDEF...,那么假设数字
x
x
x 为
A
B
C
D
E
F
ABCDEF
ABCDEF,从最高位 A 开始向后遍历,在遍历过程中有以下两种情况:
- 遍历最高位 A A A时:最高位不能为 0,所以应当从 1 开始枚举最高位 j ( 1 ≤ j ≤ A ) j(1≤ j ≤ A) j(1≤j≤A),要求低位数的封闭图形个数为 k − n u m b e r [ j ] k-number[j] k−number[j].
- 当不是最高位时,假设是
B
B
B,则
j
(
0
≤
j
≤
B
)
j(0≤j≤B)
j(0≤j≤B),则此时要求更低位数字封闭图形个数为
k
−
n
u
m
b
e
r
[
A
]
−
n
u
m
b
e
r
[
j
]
k-number[A]-number[j]
k−number[A]−number[j].其次,我们还应当考虑数字仅有 5 位的情况(因为仅有5位数的数字大小一定小于6位数的 x)
最后检查一下 x 本身的封闭图形个数是否为 k 个
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int number[]={1,0,0,0,1,0,1,0,2,1};
ll dp[15][25]; // 表示前i个数中封闭个数为j的种类数
ll l,r,k;
ll f(ll x)
{
if(x==0) return 0ll;
vector<int>num;
while(x) num.push_back(x%10),x/=10;
ll res=0,last=k,len=num.size();
int self=0;
for(int i=len-1;i>=0;i--) {
self+=number[num[i]];
for(int j=(i==(len-1));j<num[i];j++) {
if(last>=number[j])
res+=dp[i][last-number[j]];
}
if(i!=len-1) {
for(int j=1;j<=9;j++) {
if(k>=number[j])
res+=dp[i][k-number[j]];
}
}
last-=number[num[i]];
}
res+=self==k;
return res;
}
int main()
{
dp[0][0]=1;
for(int i=1;i<=12;i++)
for(int j=0;j<=24;j++)
for(int u=0;u<=9;u++)
if(j>=number[u]) dp[i][j]+=dp[i-1][j-number[u]];
cin>>l>>r>>k;
cout<<(f(r)-f(l-1))<<'\n';
return 0;
}
源石开采
通过线段树维护任意区间的最大值和次大值,求得sum。根据巴什博弈论,若sum能被m+1整除,则先手必败,否则先手必胜。
线段树某个节点的左节点最大值次大值分别为a、b,右节点为c、d,那么该节点的最大值为
m
a
x
(
a
,
c
)
max(a,c)
max(a,c),次大值为
m
a
x
(
m
i
n
(
a
,
c
)
,
m
a
x
(
b
,
d
)
)
max(min(a,c),max(b,d))
max(min(a,c),max(b,d))
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int n,q,m,arr[200010];
struct node{
int l,r,fir,sec;
}tr[200010*4];
void pushup(int u)
{
tr[u].fir=max(tr[u<<1].fir,tr[u<<1|1].fir);
tr[u].sec=max(min(tr[u<<1].fir,tr[u<<1|1].fir),max(tr[u<<1].sec,tr[u<<1|1].sec));
}
void build(int u,int l,int r)
{
if(l==r)
tr[u]={l,r,arr[r],0};
else {
int mid=l+r>>1;
tr[u].l=l,tr[u].r=r;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
pushup(u);
}
}
pii query(int u,int l,int r)
{
if(tr[u].l>=l&&tr[u].r<=r) return {tr[u].fir,tr[u].sec};
else {
int mid=tr[u].l+tr[u].r>>1;
pii a={0,0},b={0,0};
if(l<=mid) a=query(u<<1,l,r);
if(r>mid) b=query(u<<1|1,l,r);
return {max(a.first,b.first),max(min(a.first,b.first),max(a.second,b.second))};
}
}
int main()
{
ios::sync_with_stdio(false),cin.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++) cin>>arr[i];
build(1,1,n);
ll sum=0;
while(q--) {
int l,r;
cin>>l>>r;
auto res=query(1,l,r);
// cout<<res.first<<' '<<res.second<<'\n';
sum+=res.first+res.second;
}
cin>>m;
cout<<sum<<'\n';
cout<<(sum%(m+1)?"red":"blue")<<'\n';
return 0;
}