A
题意:
给定4个字符串,每次可以将一种字符串变成另一个字符串,请求最少的操作使得所有字符串相同。
核心思路:就是一个找规律的题目,哈哈哈,看多了jly的代码还是有好处的。但是需要注意memset的用法,我在题目的时候就memset(vis,0, sizeof 0),犯病了。
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N = 1e3 + 10;
unordered_map<int, int> mp;
int a[N], b[N];
int n;
char s[N][N];
int vis[N];
int erfen(int x)
{
int l = 0;
int r = n - 1;
while (l < r)
{
int mid = l + r >> 1;
if (b[mid] >= x)
r = mid;
else
l = mid + 1;
}
return l;
}
void solve()
{
int ans = 3;
for (int i = 0;i < 2;i++)
for (int j = 0;j < 2;j++)
cin >> s[i][j];
memset(vis, 0, sizeof vis);
for (int i = 0;i < 2;i++)
for (int j = 0;j < 2;j++)
{
if (!vis[s[i][j]])
{
vis[s[i][j]] = 1;
}
else
ans--;
}
cout << ans << endl;
}
int main()
{
int T;
cin >> T;
while (T--)
{
solve();
}
}
B
题意:
给定一个大小为n * m的棋盘,和一个特殊点[sx,sy]以及参数d。机器人从1,1出发到n,m,途中距离特殊点的曼哈顿距离不能小于等于d,否则就会被这个点蒸发,求机器人到n,m的最短路。
核心思路:这个的话还是需要画点图的,以那个激光点画一个十字图形就明白了。
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
unordered_map<int, int> mp;
int a[N], b[N];
int n;
int erfen(int x)
{
int l = 0;
int r = n - 1;
while (l < r)
{
int mid = l + r >> 1;
if (b[mid] >= x)
r = mid;
else
l = mid + 1;
}
return l;
}
void solve()
{
int n, m, x, y, d;
cin >> n >> m >> x >> y >> d;
if ((y - d <= 1 || x + d >= n) && (y + d >= m || x - d <= 1))
{
cout << -1 << endl;
return;
}
else
{
cout << n + m - 2<<endl;
}
}
int main()
{
int T;
cin >> T;
while (T--)
{
solve();
}
}
C
题意:
有一个不下降数组a,你构造由任意正整数构成的c数组,使得b[i] = a[i] + c[i],再将b数组排序。已知a数组和b数组,求出对于每一位i能够加上的最大和最小的c[i]。
核心思路:首先我们得注意一个特殊点,我们在求\(d_{max}\)的时候不可以直接和最大值和最小值进行比较。下面对照样例理解一下。先看样例1:
2 3 5
7 11 14
这个我们可以发现a数组的任何数字都可以变成b数组的任意数,所以直接取b数组的最大值和最小值就好了。但是我们改变下样例呢:
2 3 11
7 11 13
这种情况下11只能变为11 13,但是3却可以变为数组中的任意一个数。2也是可以的,所以这就产生了限制条件。所以我们可以发现a数组只能变为比它大的要不然d数组中就含有负数,但是题目居然给出了,那就说明肯定是有解的。
然后在更改下样例:
2 3 13
7 11 13
这哥时候我们会发现13只能变为13,所以后面的2,3就少了一个变换的范围了。从这个例子我们也可以发现我们可以从后往前递推。因为这两个数组本身也是递增的所以我们可以慢慢地缩小范围。也就是找到每一个数的变化区间,然后使用最大值和最小值计算下就好了。
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N = 3e5 + 10;
int n, m;
int ans[N][2];
int a[N], b[N];
int erfen(int x)
{
int l = 0;
int r = n - 1;
while (l < r)
{
int mid = l + r >> 1;
if (b[mid] >= x)
r = mid;
else
l = mid + 1;
}
return l;
}
void solve()
{
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
for (int i = 0; i < n; i++) cin >> b[i];
int top = n-1;
for (int i = n-1; i >= 0; i--)
{
int t = erfen(a[i]);//先找出第一个大于a[i]的值
if (t == i)//t==i说明i到n个位置已经确定好d了,需要把上确界也更新一下.
{
//cout << top << " " << t << " " << i << endl;
ans[i][0] = b[t] - a[i];
ans[i][1] = b[top] - a[i];
top = i - 1;
}
else
{
// cout << top << " " << t << " " << i << endl;
ans[i][0] = b[t] - a[i];
ans[i][1] = b[top] - a[i];
}
}
for (int i = 0; i < n; i++) cout << ans[i][0] << " "; cout << endl;
for (int i = 0; i < n; i++) cout << ans[i][1] << " "; cout << endl;
}
int main()
{
int T;
cin >> T;
while (T--)
{
solve();
}
}
D
题意:
给定长度为n的数组a和数组b,可以随意构造b的顺序,使得数组c[i] = a[i] ^ b[i],请最大化c[1] & c[2] & ... c[n]的值。
核心思路:这里我们可以发现其实一个内在的规律就是找a[i]和b[i]中的0,1使之与之组合。因为这样才可以使得这个值是最大的,所以我们可以先把某一个位置j中的0,1全都挑选出来。其中j表示的是我们当前枚举的位数,然后再判断这个情况是不是合法的,也就是判断这个位置上面a中1的是不是等于b中的0.一定要注意我们统计的是某个位置而不是全部。
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
unordered_map<int, int> mp;
LL a[N], b[N];
void solve()
{
int n;
cin >> n;
for (int i = 1;i <= n;i++)
cin >> a[i];
for (int i = 1;i <= n;i++)
cin >> b[i];
LL ans = 0;
for (int j = 30;j >= 0;j--)
{
ans |= 1 << j;
map<int, int> mpa, mpb;
for (int i = 1;i <= n;i++)
mpa[ans & a[i]]++, mpb[ans & b[i]]++;
int flag = 1;
for (int i = 1;i <= n;i++)
{
if (mpa[ans & a[i]] != mpb[ans ^ (ans & a[i])])
{
flag = 0;
break;
}
}
if (!flag)
ans -= (1 << j);
}
cout << ans << endl;
}
int main()
{
int T;
cin >> T;
while (T--)
{
solve();
}
}
小总结:代码方面不需要太死板其他博主的,主要是仿照思路就好了,然后就是看不懂的注意打量两组数据看下
标签:Educational,Rated,int,Codeforces,long,mid,solve,数组,include From: https://www.cnblogs.com/xyh-hnust666/p/16967709.html