Educational Codeforces Round 118 (Rated for Div. 2) ABCDE
A. Long Comparison
题意
t组数据,每组数据给x1、p1、x2、p2代表两个数A,B。
A是x1后面加p1个0,B是x2后面加p2个0。比较A,B的大小。
思路
先比较长度,在长度相同的时候再一位位的比较大小。
#include<bits/stdc++.h>
using namespace std;
int p1,p2,len1,len2;
string x1,x2;
void solve(){
cin>>x1>>p1>>x2>>p2;
len1=x1.length(); len2=x2.length();
if(len1+p1>len2+p2){puts(">");return;}
if(len1+p1<len2+p2){puts("<");return;}
int len=len1+p1,mi=min(len1,len2);
for(int i=0;i<mi;i++){
if(x1[i]>x2[i]){puts(">");return;}
if(x1[i]<x2[i]){puts("<");return;}
}
if(len1>len2){
for(int i=mi;i<len1;i++){
if(x1[i]!='0'){puts(">");return;}
}
puts("=");
}
else if(len1<len2){
for(int i=mi;i<len2;i++){
if(x2[i]!='0'){puts("<");return;}
}
puts("=");
}
else puts("=");
}
int main(){
int t;scanf("%d",&t);
while(t--) solve();
}
B. Absent Remainder
题意
t组数据,每组数据由一个长度为n的a数列组成。
要求输出
⌊
n
2
⌋
⌊n2⌋
⌊n2⌋ 对
x
%
y
x\%y
x%y不在a数列的元素对。
思路
直接贪心就行了,每次取y为a数列的最小值,再依次取
⌊
n
2
⌋
⌊n2⌋
⌊n2⌋个元素做x
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,a[N];
void solve(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1);
int ned=n/2;
int idx=2;
while(ned){
printf("%d %d\n",a[idx],a[1]);
ned--;idx++;
}
}
int main(){
int t;scanf("%d",&t);
while(t--) solve();
}
C. Poisoned Dagger
题意
t组数据,n个时间点可以攻击,龙的血量是h,问一次攻击持续多久可以打败龙。每次攻击在持续的时候要是到了下一个攻击时间点,那么攻击时间重新累计。
思路
cf里面很常见的一种二分,我们直接二分答案,找到最小符合条件的攻击持续时间就行了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=105;
ll n,h,a[N];
bool cek(ll mid){
ll sum=0;
for(ll i=1;i<=n;i++){
if(i!=n) sum+=min(mid,a[i+1]-a[i]);
else sum+=mid;
}
return sum>=h;
}
void solve(){
scanf("%lld%lld",&n,&h);
for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);
ll l=1,r=h,ans=h;
while(l<=r){
ll mid=(l+r)>>1;
if(cek(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
printf("%lld\n",ans);
}
int main(){
int t;scanf("%d",&t);
while(t--)solve();
return 0;
}
D. MEX Sequences
题意
一共有多少 MEX-CORRECT的序列
如果一个序列被认为是MEX-CORRECT 的 那么
∣
x
i
−
M
E
X
(
x
1
…
x
i
)
∣
<
=
1
|xi-MEX(x1…xi)|<=1
∣xi−MEX(x1…xi)∣<=1
(如果 i=1 就满足
∣
x
1
−
M
E
X
(
x
1
)
∣
<
=
1
|x1-MEX(x1)|<=1
∣x1−MEX(x1)∣<=1,如果i=2 要满足
∣
x
1
−
M
E
X
(
x
1
)
∣
<
=
1
和
∣
x
2
−
M
E
X
(
x
1
,
x
2
)
∣
<
=
1
)
|x1-MEX(x1)|<=1和 |x2-MEX(x1,x2)|<=1)
∣x1−MEX(x1)∣<=1和∣x2−MEX(x1,x2)∣<=1)
思路
计数DP,根据MEX的性质,我们知道MEX是序列中没有出现的最小非负数,那么要满足
∣
x
i
−
M
E
X
(
x
1
…
x
i
)
∣
<
=
1
|xi-MEX(x1…xi)|<=1
∣xi−MEX(x1…xi)∣<=1,(根据样例1也可以知道),我们也知道满足条件的只有两种情况。
①:0 0 1 1 2 2 这样从0开始一直前后变化+0、+1
②:0 0 1 1 3 3 1 1 中间只缺了一个数字
然后写DP就行了,注意开longlong,和最后答案mod998244353
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=5e5+5;
const ll mod=998244353;
ll n,dp[N][2];//0为情况①,1为情况②
void solve(){
scanf("%lld",&n);
dp[0][0]=1;
for(ll i=1;i<=n;i++){
ll x;scanf("%lld",&x); x++;
dp[x][0]=(dp[x][0]+dp[x][0])%mod;
dp[x][0]=(dp[x][0]+dp[x-1][0])%mod;
if(x>=2) dp[x][1]=(dp[x][1]*2%mod+dp[x-2][0])%mod;
if(x<=n-2) dp[x+2][1]=(dp[x+2][1]+dp[x+2][1])%mod;
}
ll sum=0;
for(ll i=1;i<=n+2;i++){
sum+=(dp[i][0]+dp[i][1])%mod;
dp[i][0]=dp[i][1]=0;
}
printf("%d\n",sum%mod);
}
int main(){
int t;scanf("%d",&t);
while(t--) solve();
}
E. Crazy Robot
题意
有一个不听话的机器人,不会按照执行移动,即你说往左,它绝不往左;说往右,它绝不往右。同时在地图上有墙(‘#’),有目的地(‘L’),有空地(‘.’),要求我们将一定可以到达的空地变成(‘+’),然后输出新地图。
思路
直接bfs,听说复杂度可以过???然后对于加入队列的点,需要满足在通过上一个点bfs判断的时候,周围只有一个方向移动就行了。就for方向的时候,多for一次方向,记录一下可以移动的方向就好了。(具体看代码)
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int,int>PII;
const int N=1e6+5;
int n,m;
map<PII,bool>vis;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
char s[N];
int sx,sy;
vector<char>mp[N];
void bfs(int xx,int yy){
queue<PII>q;
q.push({xx,yy});
vis[{xx,yy}]=true;
while(!q.empty()){
auto u=q.front(); q.pop();
for(int i=0;i<4;i++){
int nx=u.x+dx[i],ny=u.y+dy[i];
if(nx>=0&&nx<n&&ny>=0&&ny<m&&!vis[{nx,ny}]&&mp[nx][ny]=='.'){
int cnt=0;
for(int j=0;j<4;j++){
int bx=nx+dx[j];
int by=ny+dy[j];
if(bx==u.x&&by==u.y) continue;
if(bx>=0&&bx<n&&by>=0&&by<m&&mp[bx][by]=='.') cnt++;
}
if(cnt<=1){
mp[nx][ny]='+';
vis[{nx,ny}]=true;
q.push({nx,ny});
}
}
}
}
}
void solve(){
vis.clear();
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
mp[i].clear();
for(int j=0;j<m;j++){
char op; scanf(" %c",&op);
if(op=='L'){sx=i,sy=j;}
mp[i].push_back(op);
}
}
bfs(sx,sy);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
printf("%c",mp[i][j]);
}
printf("\n");
}
}
int main(){
int t;scanf("%d",&t);
while(t--) solve();
}
F. Tree Coloring
思路
我也不会