A - Not
签到题
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int main()
{
IO;
int T=1;
//cin>>T;
while(T--)
{
int x;
cin>>x;
cout<<1-x<<endl;
}
return 0;
}
B - Product Max
签到题
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=100010;
int main()
{
IO;
int T=1;
//cin>>T;
while(T--)
{
ll a,b,c,d;
cin>>a>>b>>c>>d;
cout<<max(max(a*c,a*d),max(b*c,b*d))<<endl;
}
return 0;
}
C - Ubiquity
正难则反,容斥原理
先只考虑满足第一个情况的方案数:
1
0
n
10^n
10n
那么其中肯定有不满足第二个情况和第三个情况的方案,我们只要减去这种情况即可。
满足第一个条件,不满足第二个条件的方案数是
9
n
9^n
9n
满足第一个条件,不满足第三个条件的方案数是
9
n
9^n
9n
满足第一个条件,同时不满足第二个条件和第三个条件的方案数是
8
n
8^n
8n
根据容斥原理,满足第一个条件但是不满足第二个条件或者第三个条件的方案数是
9
n
+
9
n
−
8
n
9^n+9^n-8^n
9n+9n−8n
因此答案是
1
0
n
−
(
9
n
+
9
n
−
8
n
)
10^n-(9^n+9^n-8^n)
10n−(9n+9n−8n)
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=100010;
const ll mod=1e9+7;
ll qmi(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
int main()
{
IO;
int T=1;
//cin>>T;
while(T--)
{
ll n;
cin>>n;
cout<<((qmi(10ll,n)-2*qmi(9ll,n)+qmi(8ll,n))%mod+mod)%mod<<'\n';
}
return 0;
}
D - Redistribution
考试的时候老想着完全背包。。
f
[
i
]
f[i]
f[i]表示用
3
…
i
3 \dots i
3…i这些数凑成和是
i
i
i的方案数
转移:考虑最后一个数用的是谁?
f
[
i
]
=
f
[
i
−
3
]
+
f
[
i
−
4
]
+
⋯
+
f
[
i
−
i
]
f[i]=f[i-3]+f[i-4]+\dots+f[i-i]
f[i]=f[i−3]+f[i−4]+⋯+f[i−i]
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=2010;
const ll mod=1e9+7;
ll f[N];
int main()
{
IO;
int T=1;
//cin>>T;
while(T--)
{
int s;
cin>>s;
f[0]=1;
for(int i=3;i<=s;i++)
for(int j=3;j<=i;j++)
f[i]=(f[i]+f[i-j])%mod;
cout<<f[s]<<'\n';
}
return 0;
}
E - Dist Max
考虑两个点
(
x
1
,
y
1
)
(x_1,y_1)
(x1,y1)和
(
x
2
,
y
2
)
(x_2,y_2)
(x2,y2)的曼哈顿距离
∣
x
1
−
x
2
∣
+
∣
y
1
−
y
2
∣
|x_1-x_2|+|y_1-y_2|
∣x1−x2∣+∣y1−y2∣其实还可以进一步简化成
m
a
x
(
∣
(
x
1
+
y
1
)
−
(
x
2
+
y
2
)
∣
,
∣
(
x
1
−
y
1
)
−
(
x
2
−
y
2
)
∣
)
max(|(x_1+y_1)-(x_2+y_2)|,|(x_1-y_1)-(x_2-y_2)|)
max(∣(x1+y1)−(x2+y2)∣,∣(x1−y1)−(x2−y2)∣)
由此将问题降维,然后就很容易解了。
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=200010;
int d1[N],d2[N],n;
int main()
{
IO;
int T=1;
//cin>>T;
while(T--)
{
cin>>n;
for(int i=1;i<=n;i++)
{
int x,y;
cin>>x>>y;
d1[i]=x+y;
d2[i]=x-y;
}
sort(d1+1,d1+1+n);
sort(d2+1,d2+1+n);
cout<<max(d1[n]-d1[1],d2[n]-d2[1])<<'\n';
}
return 0;
}
无意中看到一个知识,此题转化更专业的叫法曼哈顿距离与切比雪夫距离的转换
F - Contrast
结论:将 B 按降序排序后,B 中最多只会有一段
B
[
l
∼
r
]
B[l∼r]
B[l∼r] 与
A
[
l
∼
r
]
A[l∼r]
A[l∼r] 是相同的,且
A
[
l
∼
r
]
A[l∼r]
A[l∼r] 和
B
[
l
∼
r
]
B[l∼r]
B[l∼r] 中所有值都等于同一个数
v
a
l
val
val,仔细想想便可得到此结论。
把这些相等的位置记下来,然后与其他的位置交换,此位置序还需满足
a
i
≠
v
a
l
a_i\ne val
ai=val,每找到一个位置就可以交换一次,如果位置不够则不可能满足题意。
还有一个判断不满足题意的方法即统计a[]
和b[]
每个数出现的次数cnta[]
和cntb[]
,对于每一个
i
i
i满足
c
n
t
a
i
+
c
n
t
b
i
≤
n
cnta_i+cntb_i\leq n
cntai+cntbi≤n才可能构造出一组解,否则不可能满足题意。
口胡证明:对于a[]
中的i
需要b[]
至少存在有cnta[i]
个不等于i
的数与之配对,即cnta[i]<=n-cntb[i]
,证毕。
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=200010;
int a[N],b[N],n;
int main()
{
IO;
int T=1;
//cin>>T;
while(T--)
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
reverse(b+1,b+1+n);
vector<int> p,q;
int val=0,cnt=0;
for(int i=1;i<=n;i++)
{
if(a[i]!=b[i]) continue;
cnt++;
p.push_back(i);
val=b[i];
}
for(int i=1;i<=n;i++)
{
if(!cnt) break;
if(a[i]==b[i]) continue;
if(a[i]!=val&&b[i]!=val)
{
cnt--;
q.push_back(i);
}
}
if(cnt) return cout<<"No\n",0;
for(int i=0;i<q.size();i++) swap(b[p[i]],b[q[i]]);
cout<<"Yes\n";
for(int i=1;i<=n;i++) cout<<b[i]<<' ';
cout<<'\n';
}
return 0;
}
ABC现在看来以及没有想象中那么难,自己现在都可以接受。
正式上课了,要加油哦~