1011.NOI2024
题意:
有m个人,n场比赛。
第
i
i
i场比赛你获得
a
i
a_i
ai名,总分为
b
i
b_i
bi,选手分数为
1
1
1~
b
i
b_i
bi。
名次为分数严格大于你的人数+1.
最后排名不超过
k
k
k的人拿到冠军.
问最后你是否一定能拿冠军。
题解:
最极端的情况,每次比赛都是0分。有
a
i
−
1
a_i-1
ai−1个人拿满分。那这
a
i
−
1
a_i-1
ai−1个人的排名一定都在你之上。
最后比较排名在你之上的人数有没有
k
k
k人。
还有
k
=
m
k=m
k=m时,一定可以拿冠军。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef __int128 i128;
typedef long long ll;
typedef double db;
const db PI = acos(-1);
typedef array<ll, 2> PII; // vector<PII> a(n + 1);
const ll inf = 2e18 + 10;
const int mod = 998244353;
const int maxn = 2e5 + 10;
bool multi = 1;
void Solve() {
ll n, m, k; cin >> n >> m >> k;
vector<ll> a(n + 1), b(n + 1);
ll summ = 0;
for(ll i = 1; i <= n; i ++ ) {
cin >> a[i];
summ += a[i] - 1;
}
for(ll i = 1; i <= n; i ++ ) {
cin >> b[i];
}
if(k == m || summ < k) {
cout << "YES\n";
} else {
cout << "NO\n";
}
}
signed main() {
// freopen("test.in","r",stdin);
// freopen("code.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
ll T = 1;
if(multi) cin >> T;
while(T -- ) {
Solve();
}
return 0;
}
1008.SunBian
题意:
有n个成环的竹笋。
Alice 和 Bob 轮流执行如下,选择
[
1
,
k
]
[1,k]
[1,k]个连续竹笋拿走。Alice优先。
无法操作者输。
两人都绝顶聪明,问谁最后会赢。
题解:
情况1:
n
=
k
n=k
n=k
Alice第一次操作直接全部拿走,必胜。
情况2:
k
=
1
k=1
k=1
每次拿一个,最后就是看n的奇偶性。
其余情况:
无论Alice拿多少个,Bob都可以取中间的1或2,分为两个一样长的连续段,无论Alice怎么操作,Bob都可以进行对称操作,那最后一步一定是Bob操作。Bob必胜。
代码:
#include <bits/stdc++.h>
#define int long long
#define PII pair<int,int>
using namespace std;
const int N =2e6+6;
int a[N];
void solve()
{
int n,k;
cin>>n>>k;
if(n==k){
cout<<'A';
return ;
}
if(k==1){
if(n%2){
cout<<'A';
}else cout<<'B';
return ;
}
cout<<'B';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T=1;
cin>>T;
while(T--){
solve();
}
return 0;
}
1002.scenery
题意:
有n处地点要拍摄,一天有m段时间。
每处地点要在
l
i
l_i
li~
R
i
R_i
Ri的时间段拍摄,拍摄时间为连续的
t
i
t_i
ti个时间段。
同一时间只能拍摄一处地方。问是否可以拍摄完这n处地方。
保证
l
i
+
1
<
=
l
i
,
r
i
+
1
>
=
r
i
l_{i+1}<=l_i,r_{i+1}>=r_i
li+1<=li,ri+1>=ri
题解:
画图,发现就是一层一层的,可以用dp思想解决。
假如前
i
i
i处拍摄在
x
x
x~
y
y
y时间段:
那第
i
+
1
i+1
i+1处只可能在
x
x
x左边,或者
y
y
y右边。发现直线拍摄时间段都是相邻的,这样肯定是最优的选择。
d
p
[
i
]
[
j
]
=
0
/
1
dp[i][j]=0/1
dp[i][j]=0/1表示第
i
i
i层,以
j
j
j为x的时间段是否满足。
转移方程:
d
p
[
i
]
[
j
]
=
1
dp[i][j]=1
dp[i][j]=1
在
x
x
x左边:
如果
j
−
t
[
i
+
1
]
>
=
l
[
i
+
1
]
j-t[i+1]>=l[i+1]
j−t[i+1]>=l[i+1] ->
d
p
[
i
+
1
]
[
j
−
t
[
i
+
1
]
]
=
1
dp[i+1][j-t[i+1]]=1
dp[i+1][j−t[i+1]]=1
在
y
y
y右边:
如果:
j
+
s
u
m
[
i
+
1
]
−
1
<
=
r
[
i
+
1
]
j+sum[i+1]-1<=r[i+1]
j+sum[i+1]−1<=r[i+1] ->
d
p
[
i
+
1
]
[
j
]
=
1
dp[i+1][j]=1
dp[i+1][j]=1
代码:
#include <bits/stdc++.h>
#define int long long
#define PII pair<int,int>
using namespace std;
const int N =5e3+6;
int dp[N][N];
int l[N],r[N],sum[N],t[N];
void solve()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>l[i]>>r[i]>>t[i];
sum[i]=sum[i-1]+t[i];
}
for(int i=1;i<=n;i++){
for(int j=0;j<=m;j++){
dp[i][j]=0;
}
}
for(int i=l[1];i+t[1]-1<=r[1];i++){
dp[1][i]=1;
}
for(int i=1;i<n;i++){
for(int j=1;j<=m;j++){
if(dp[i][j]){
if(j-t[i+1]>=l[i+1]){
dp[i+1][j-t[i+1]]=1;
}
if(j+sum[i+1]-1<=r[i+1]){
dp[i+1][j]=1;
}
}
}
}
int ok=0;
for(int i=1;i<=m;i++){
if(dp[n][i])ok=1;
}
if(ok){
cout<<"YES\n";
}else cout<<"NO\n";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T=1;
cin>>T;
while(T--){
solve();
}
return 0;
}
1010.A+B Problem
题意:
给定
a
i
,
b
i
a_i,b_i
ai,bi,构造出数组
c
c
c.
满足
(
a
i
x
o
r
c
i
−
1
)
+
(
b
i
x
o
r
c
i
−
1
)
=
c
i
(a_i xor c_{i-1})+(b_i xor c_{i-1})=c_i
(aixorci−1)+(bixorci−1)=ci,特别
c
0
=
c
q
c_0=c_q
c0=cq
并且要求c数组为字典序最小。
题解:
a
i
a_i
ai和
b
i
b_i
bi最低位情况:
0 0 /1 1 最后无论异或多少,结果都是0
1 0 /0 1 最后无论异或多少,结果都是1
判断每一位的情况,就知道 c i c_i ci的值。
代码:
#include <bits/stdc++.h>
using namespace std;
#define int unsigned int
#define rep(i,j,k) for (int i=(j);i<=(k);i++)
const int N=1000005;
int n,m,sn;
int a[N],b[N],c[N];
void work()
{
cin >> n;
rep(i,0,n-1) cin >> a[i] >> b[i];
rep(i,0,n-1) c[i]=(a[i]^b[i])&1;
rep(k,1,31)
{
rep(i,0,n-1)
{
int bas=c[(i+n-1)%n]&((1<<k)-1);
int d=(a[i]^bas)+(b[i]^bas);
c[i]^=d&(1u<<k);
}
}
rep(i,0,n-1) cout << c[i] << '\n';
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T;
cin >> T;
while (T--) work();
return 0;
}