A - Shortest Path with Obstacle
思路
在一条直线上,且在起点和终点之间就绕路
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int main ()
{
int t;
cin >> t;
while (t --)
{
int xa, xb, xf, ya, yb, yf;
cin >> xa >> ya >> xb >> yb >> xf >> yf;
if (xa == xb && xa != xf)
cout << abs (ya - yb) << endl;
else if (ya == yb && ya != yf)
cout << abs (xa - xb) << endl;
else if (xa == xb && (xa == xf && min (ya, yb) < yf && max (ya, yb) > yf))
cout << abs (ya - yb) + 2 << endl;
else if (ya == yb && (ya == yf && min (xa, xb) < xf && max (xa, xb) > xf))
cout << abs (xa - xb) + 2 << endl;
else
cout << abs (xa - xb) + abs (ya - yb) << endl;
}
}
B - Alphabetical Strings
思路
找到a,前面递减,后面递增,再判断排序完了的结果是否缺字母
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int a[30];
int main ()
{
int t;
cin >> t;
int b[30];
for (int i = 0; i < 26; i ++)
b[i] = i;
while (t --)
{
string tmp;
int flag = -1, maxx = -1;
bool f = true;
cin >> tmp;
for (int i = 0; i < tmp.length (); i ++)
{
a[i] = tmp[i] - 'a';
if (a[i] == 0)
flag = i;
if (a[i] > maxx)
maxx = a[i];
}
// cout << " <<<< " << flag << endl;
// cout << " <<<< " << maxx << endl;
if (flag == -1)
f = false;
else if (flag == 0 && tmp.length () == 1)
f = true;
else
{
if (maxx != tmp.length () - 1)
f = false;
for (int i = 0; i < flag; i ++)
{
if (a[i] <= a[i + 1])
{
f = false;
}
}
for (int i = flag; i < tmp.length () - 1; i ++)
{
if (a[i] >= a[i + 1])
{
f = false;
}
}
sort (a, a + tmp.length ());
for (int i = 0; i < tmp.length (); i ++)
if (a[i] != b[i])
f = false;
}
if (f) cout << "YES" << endl;
else
cout << "NO" << endl;
}
}
C - Pair Programming
思路
有0先放0,没0判断这行存在不存在
#include <iostream>
using namespace std;
int main ()
{
int t;
cin >> t;
while (t --)
{
int k, n, m, x = 0;
int a[110], b[110], ans[220];
bool f = 0;
cin >> k >> n >> m;
for (int i = 1; i <= n; i ++)
cin >> a[i];
for (int i = 1; i <= m; i ++)
cin >> b[i];
int na = 1, nb = 1;
while (1)
{
if (na == n + 1 && nb == m + 1) f = 1;
if (a[na] <= k && na <= n)
{
ans[na + nb - 1] = a[na];
if (a[na] == 0) k ++;
na ++;
continue;
}
if (b[nb] <= k && nb <= m)
{
ans[na + nb - 1] = b[nb];
if (b[nb] == 0) k ++;
nb ++;
continue;
}
break;
}
if (f)
{
for (int i = 1; i <= n + m; i ++)
cout << ans[i] << " ";
cout << endl;
}
else
cout << -1 << endl;
}
}
D - Co-growing Sequence
题目大意
给你一个序列x,让你寻找一个最小的序列y,使得x[i] ^= y[i],x[i] & x[i + 1] = x[i]
思路
二进制表示下a[i]的第k位为1,则a[i+1]第k位也必须为1,且维护一个当前最大值x。
这样的话,如果a[i + 1]的第k位为0,而a[i]的第k位为1,要把a[i + 1]的第k位变为1。对a[i + 1]按位取反后,~a[i+1]的第k位为1,此时x & ~a[i + 1]的第k位就为1,原本a[i + 1]中为1的,就会变成0,不需要加,根据二进制的加法法则,可知需要加上的数tmp便为x & ~a[i + 1]。
然后再更新x,x = a[i] ^tmp(或x = a[i] + tmp)便为当前最大值,即改变后的a[i + 1]
例如:a[i] = 1101, a[i + 1] = 1011, 此时a[i + 1]第2位不为1,但a[i]第2位为1,所以要给a[i + 1]加上100,使其变为1011 + 100 = 1111,其中100便为1101 & ~1011 = 1101 & 100 = 100。
#include <iostream>
using namespace std;
const int N = 2e5 + 10;
int a[N];
int main ()
{
int t;
cin >> t;
while (t --)
{
int n;
cin >> n;
int x = 0;
for (int i = 1; i <= n; i ++)
{
cin >> a[i];
int tmp = x & (~a[i]);
cout << tmp << " ";
x = a[i] ^ tmp; // 或 x = a[i] + tmp;
}
cout << endl;
}
}
题目大意
每个格子i的温度,是空调温度,加上空调离格子i的距离的最小值,即
m
i
n
1
≤
j
≤
k
(
t
j
+
∣
a
j
−
i
∣
)
min_{1≤j≤k}(t_j+|a_j−i|)
min1≤j≤k(tj+∣aj−i∣)
求每个格子的空调温度
思路
贪心,从前往后跑一遍,从后往前跑一遍,取最小即可。
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
int main ()
{
int q;
cin >> q;
while (q --)
{
int n, k;
cin >> n >> k;
vector <int> a (k);
for (int i = 0; i < k; i ++)
cin >> a[i];
vector <int> t (k);
for (int i = 0; i < k; i ++)
cin >> t[i];
vector <ll> c (n, INT_MAX);
for (int i = 0; i < k; i ++)
c[a[i] - 1] = t[i];
ll p;
vector <ll> L (n, INT_MAX);
p = INT_MAX;
for (int i = 0; i < n; i ++)
{
p = min (p + 1, c[i]);
L[i] = p;
}
vector <ll> R (n, INT_MAX);
p = INT_MAX;
for (int i = n - 1; i >= 0; i --)
{
p = min (p + 1, c[i]);
R[i] = p;
}
for (int i = 0; i < n; i ++)
cout << min (L[i], R[i]) << " ";
cout << endl;
}
}