场次链接
成功上橙!!
A、Three Strings
题目链接
给你a,b,c,3个串,对于a,b,c的每一位你必须将 a i , c i a_i,c_i ai,ci互换或者 b i , c i b_i,c_i bi,ci互换,问是否有可能使得a串等于b串。
数据范围 1 ≤ t ≤ 100 1\leq t\leq 100 1≤t≤100, 1 ≤ ∣ s ∣ ≤ 100 1\leq |s|\leq 100 1≤∣s∣≤100
解 对于每一位判断 a i = = c i a_i==c_i ai==ci或 b i = = c i b_i==c_i bi==ci即可
复杂度 O ( ∣ s ∣ ) O(|s|) O(∣s∣)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
char a[105],b[105],c[105];
void work()
{
scanf("%s%s%s",a,b,c);
int l=strlen(a);
for(int i=0;i<l;i++){
if(a[i]!=c[i]&&b[i]!=c[i]){
printf("NO\n");
return;
}
}
printf("YES\n");
}
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int T=1;
scanf("%d",&T);
//cin>>T;
while(T--){
work();
}
}
B、Motarack’s Birthday
题目链接
给n个数,你要求相邻2个数差的绝对值的最大值,值为-1的位置你可以统一变成一个数,问这个最大值和你将-1变成什么数。
数据范围 1 ≤ t ≤ 1 0 4 1\leq t\leq 10^4 1≤t≤104, 2 ≤ n ≤ 1 0 5 2\leq n\leq 10^5 2≤n≤105, − 1 ≤ a i ≤ 1 0 9 -1\leq a_i\leq 10^9 −1≤ai≤109
解 先将没有-1的情况的最大值统计出来,然后把有-1的位置的相邻的数的最大值最小值统计出来,要填入的数即(max+min)/2,再求个最大值即可。
复杂度 O ( n ) O(n) O(n)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[100005];
void work()
{
int n;
scanf("%d",&n);
int maxx=0;
int minn=1e9;
int ans=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++){
if(i>1){
if(a[i]==-1){
if(a[i-1]!=-1){
maxx=max(a[i-1],maxx);
minn=min(a[i-1],minn);
}
}
}
if(i<n){
if(a[i]==-1){
if(a[i+1]!=-1){
maxx=max(a[i+1],maxx);
minn=min(a[i+1],minn);
}
}
}
}
for(int i=2;i<=n;i++){
if(a[i]!=-1&&a[i-1]!=-1){
ans=max(ans,abs(a[i]-a[i-1]));
}
}
printf("%d %d\n",max(ans,(maxx-minn+1)/2),(maxx+minn)/2);
}
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int T=1;
scanf("%d",&T);
//cin>>T;
while(T--){
work();
}
}
C、Ayoub’s function
题目链接
给一个n,m,即在一个n长度的字符串中有m个1,这m个1的位置可以任选,要求最大有多少个子段存在1。
数据范围 1 ≤ t ≤ 1 0 5 1\leq t\leq 10^5 1≤t≤105, 1 ≤ n ≤ 1 0 9 1\leq n\leq 10^9 1≤n≤109, 0 ≤ m ≤ n 0\leq m\leq n 0≤m≤n
解 答案就是所有子段减掉全0子段的数量,即将n-m个0平均分为m+1份,计算即可。
复杂度 O ( 1 ) O(1) O(1)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
void work()
{
ll n,m;
scanf("%lld%lld",&n,&m);
if(m==0){
printf("0\n");
return;
}
ll ans=n*(n+1)/2;
n=n-m;
ll tmp=n/(m+1);
ll tmp1=n%(m+1);
ans-=(tmp+1)*(tmp+2)/2*tmp1;
ans-=tmp*(tmp+1)/2*(m+1-tmp1);
printf("%lld\n",ans);
}
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int T=1;
scanf("%d",&T);
//cin>>T;
while(T--){
work();
}
}
D、Time to Run
给你n*m的矩阵,每个格子分别有一条有向边指向相邻的格子,你开始在(1,1),需要走k步,要求不经过同一条边,最后停在任意位置,问走法或者无法走成功,走法输出要求少于3000行,输出格式为总行数,然后后面跟上每一步的方向和步数。
数据范围 1 ≤ n , m ≤ 500 1\leq n,m\leq 500 1≤n,m≤500, 1 ≤ k ≤ 1 0 9 1\leq k\leq 10^9 1≤k≤109
解 首先可以确定 所有边都是可以经过的 那么k的范围只要在边数以内即可, n , m > = 2 n,m>=2 n,m>=2时边数为 4 ∗ n ∗ m − 2 ∗ n − 2 ∗ m 4*n*m-2*n-2*m 4∗n∗m−2∗n−2∗m,n为1时边数为 2 ∗ ( m − 1 ) 2*(m-1) 2∗(m−1),m为1时边数为 2 ∗ ( n − 1 ) 2*(n-1) 2∗(n−1)。n=1和m=1的时很好写。对于n>1并且m>1时,选择的走法可以是先右到底,然后往左走回来,再往下一格,这样所有横向边全部可以走过,然后在走到最后一行回来时,将纵向边也走掉即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node
{
char a;
int s;
}ans[3005];
void work()
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
if(m==1){
if(k>2*n-2){
printf("NO\n");
return;
}
printf("YES\n");
if(k>n-1){
printf("2\n");
printf("%d %c\n",n-1,'D');
printf("%d %c\n",k-n+1,'U');
}else{
printf("1\n%d %c\n",k,'D');
}
return;
}
if(n==1){
if(k>2*m-2){
printf("NO\n");
return;
}
printf("YES\n");
if(k>m-1){
printf("2\n");
printf("%d %c\n",m-1,'R');
printf("%d %c\n",k-m+1,'L');
}else{
printf("1\n%d %c\n",k,'R');
}
return;
}
int sum=4*n*m-2*n-2*m;
if(sum<k){
printf("NO\n");return;
}
int cnt=0;
for(int i=1;i<n;i++){
if(k>=2*m-1){
ans[++cnt].a='R';
ans[cnt].s=m-1;
ans[++cnt].a='L';
ans[cnt].s=m-1;
ans[++cnt].a='D';
ans[cnt].s=1;
k-=2*m-1;
}else if(k>m-1){
ans[++cnt].a='R';
ans[cnt].s=m-1;
ans[++cnt].a='L';
ans[cnt].s=k-m+1;
k=0;break;
}else if(k>0){
ans[++cnt].a='R';
ans[cnt].s=k;
k=0;
break;
}else{
break;
}
}
if(k>0){
ans[++cnt].a='R';
ans[cnt].s=min(k,m-1);
k-=min(k,m-1);
}
for(int i=m;i>1;i--){
if(k>=2*n-1){
ans[++cnt].a='U';
ans[cnt].s=n-1;
ans[++cnt].a='D';
ans[cnt].s=n-1;
ans[++cnt].a='L';
ans[cnt].s=1;
k-=2*n-1;
}else if(k>n-1){
ans[++cnt].a='U';
ans[cnt].s=n-1;
ans[++cnt].a='D';
ans[cnt].s=k-n+1;
k=0;break;
}else if(k>0){
ans[++cnt].a='U';
ans[cnt].s=k;
k=0;
break;
}else{
break;
}
}
if(k!=0){
ans[++cnt].a='U';
ans[cnt].s=k;
}
printf("YES\n");
printf("%d\n",cnt);
for(int i=1;i<=cnt;i++){
printf("%d %c\n",ans[i].s,ans[i].a);
}
}
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int T=1;
//scanf("%d",&T);
//cin>>T;
while(T--){
work();
}
}