Codeforces Round #619 (Div. 2)
A. Three Strings
有三个长度相等字符串a,b,c,对于每一位,a或者b必须和c进行交换,问最后能否a等于b
显然,对于每一位要么a等于c,要么b等于c,否则就不可能相等
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define int long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 201110;
const int M = 1e9+7;
int n,m;
signed main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
int T;
cin>>T;
while(T--)
{
string a,b,c;
cin>>a>>b>>c;
n = a.size();
bool ok = 1;
for(int i = 0; i < n; i++)
{
if(a[i] != c[i] && b[i] != c[i]) ok = 0;
}
if(ok) puts("YES");
else puts("NO");
}
return 0;
}
B. Motarack's Birthday
给你一个数组,问把数组中的-1替换成什么数会使得整个数组相邻的差值最小,并输出最小值
我们只需要记录与-1相邻的数的最大和最小值,然后取平均数就是最优的
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define int long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 201110;
const int M = 1e9+7;
int n,m;
int a[maxn];
signed main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
cin>>n;
for(int i = 1; i <= n; i++)
{
cin>>a[i];
}
int ans = 0,k = 0;
int mi = inf,mx = 0;
int temp = 0;
for(int i = 1; i <= n; i++)
{
if(a[i] == -1)
{
if(i > 1 && a[i-1] != -1)
{
mx = max(mx,a[i-1]);
mi = min(mi,a[i-1]);
}
if(i < n && a[i+1] != -1)
{
mx = max(mx,a[i+1]);
mi = min(mi,a[i+1]);
}
}
else
{
if(i > 1 && a[i-1] != -1)
{
temp = max(temp,abs(a[i]-a[i-1]));
}
if(i < n && a[i+1] != -1)
{
temp = max(temp,abs(a[i]-a[i+1]));
}
}
}
ans = (mx+mi)/2;
temp = max(temp,mx-ans);
cout<<temp<<' '<<ans<<endl;
}
return 0;
}
C. Ayoub's function
长度为n的01字符串,有m个1,问如何排列会使得有1的子串数目最大
包含1的子串的数量等于所有子串的数量减去只有0的子串的数量
m个1可以分成m+1段,每一段0的子串的数量等于\({l \times (l + 1)} \over 2\)
平均分配就是最优的
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define int long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 201110;
const int M = 1e9+7;
int n,m;
signed main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
int T;
cin>>T;
while(T--)
{
cin>>n>>m;
int sum = (n-m); //一共n-m个0
int avg = (n-m)/(m+1); //分成m+1段,平均每段(n-m)/(m+1)
int b = (n-m)%(m+1); //余下的
int ans = n*(n+1)/2 - (m+1-b)*avg*(avg+1)/2 - b*(avg+1)*(avg+2)/2;
cout<<ans<<endl;
}
return 0;
}
D. Time to Run
题意就懒得说了,跑的方法有很多种,就是要尽量把边跑满,具体看代码
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 201110;
const int M = 1e9+7;
int n,m,k;
vector<int> num;
vector<string> ss;
void move(int res,string s)
{
if(k == 0 || res == 0) return;
int len = s.size();
if(k >= res*len)
{
num.push_back(res);ss.push_back(s);
k -= res*len;
}
else
{
int a = k/len;
if(a){ num.push_back(a);ss.push_back(s);}
k %= len;
if(k) num.push_back(1);ss.push_back(s.substr(0,k));
k = 0;
}
}
signed main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
cin>>n>>m>>k;
int sum = (4*n*m-2*n-2*m);
if(k > sum)
{
puts("NO");
return 0;
}
puts("YES");
int h = 1;
while(k && h <= n)
{
if(h%2) move(m-1,"R");
else move(m-1,"L");
if(h < n) move(1,"D");
h++;
}
h = n;
while(k && h > 1)
{
if(h%2) move(m-1,"UDL");
else move(m-1,"UDR");
move(1,"U");
h--;
}
move(m-1,"L");
int ans = num.size();
cout<<ans<<endl;
for(int i = 0; i < ans; i++)
{
cout<<num[i]<<' '<<ss[i]<<endl;
}
return 0;
}
F. Super Jaber
多源bfs,两点间的距离,枚举一种中间颜色就行了
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
//#define int long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 1110;
const int M = 1e9+7;
//多源bfs
//对于每个颜色的其他全部颜色,仅仅访问一次
int n,m;
int col[40][maxn][maxn];
vector<pii> v[maxn];
queue<pii> q;
int to[4][2] = {0,1,1,0,0,-1,-1,0};
bool vis[40];
void bfs(int k)
{
for(auto i : v[k])
{
col[k][i.first][i.second] = 0;
q.push(i);
}
mem(vis,0);
int x,y;
while(!q.empty())
{
x = q.front().first;
y = q.front().second;
q.pop();
if(!vis[col[0][x][y]]) //每个颜色访问一次就够了
{
vis[col[0][x][y]] = 1;
for(auto i : v[col[0][x][y]])
{
int r = i.first;
int c = i.second;
if(col[k][r][c] == -1)
{
col[k][r][c] = col[k][x][y] + 1;
q.push({r,c});
}
}
}
for(int i = 0; i < 4; i++)
{
int r = x+to[i][0];
int c = y+to[i][1];
if(r <= n && r >= 1 && c <= m && c >= 1 && col[k][r][c] == -1)
{
col[k][r][c] = col[k][x][y] + 1;
q.push({r,c});
}
}
}
}
signed main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
int k;
cin>>n>>m>>k;
mem(col,-1);
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
cin>>col[0][i][j];
v[col[0][i][j]].push_back({i,j});
}
}
for(int i = 1; i <= k; i++)
{
bfs(i);
}
int q;
cin>>q;
for(int i = 0; i < q; i++)
{
int c1,r1,c2,r2;
cin>>r1>>c1>>r2>>c2;
int ans = abs(r1-r2) + abs(c1-c2); //哈密顿距离
for(int j = 1; j <= k; j++)
{
ans = min(ans,col[j][r1][c1]+col[j][r2][c2] + 1);
}
cout<<ans<<endl;
}
return 0;
}