目录
A. Odd One Out
B. Not Quite Latin Square
C. Can I Square?
D. Unnatural Language Processing
E. Romantic Glasses
F. Greetings
A. Odd One Out
Problem - A - Codeforces
输出一个不同于其他两个数的数,用异或操作可以轻松解决。
void solve{
int a,b,c;
cin>>a>>b>>c;
cout<<a^b^c<<"\n";
}
B. Not Quite Latin Square
Problem - B - Codeforces
找到?的位置,再分析它这行和列出现的元素。
char a[30][30];
void solve()
{
int x, y;
for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= 3; j++)
{
cin >> a[i][j];
if (a[i][j] == '?')
{
x = i, y = j;
}
}
}
int f[200];
memset(f, 0, sizeof(f));
for (int i = 1; i <= 3; i++)
{
f[a[x][i]]++;
f[a[i][y]]++;
}
for (int i = 'A'; i <= 'C'; i++)
{
if (!f[i])
{
cout << (char)i << "\n";
}
}
}
C. Can I Square?
Problem - C - Codeforces
数组所有元素的和是否为完全平方数。
void solve()
{
int n;
cin >> n;
ll sum = 0;
for (int i = 1; i <= n; i++)
{
ll x;
cin >> x;
sum += x;
}
if ((double)sqrt(sum) == (int)sqrt(sum))
{
cout << "YES\n";
}
else cout << "NO\n";
}
D. Unnatural Language Processing
Problem - D - Codeforces
规定一个规则。
当出现CC的子串,那么它们中间必定插入一个'.',再判断一些V后面是否插入'.',如果V后面是CC子串则不插入,或者V位于倒数第二个元素后面也不执行插入,反之都插入。
ll pos[N];
void solve()
{
memset(pos, 0, sizeof(pos));
int n;
cin >> n;
string s,t,ans;
t.resize(n + 1);
cin >> s;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == 'a' || s[i] == 'e') t[i] = 'V';
else t[i] = 'C';
}
for (int i = 0; i < s.size() - 1; i++)
{
if (t[i] == 'C' && t[i + 1] == 'C')
{
pos[i] = 1;
}
}
for (int i = 0; i < s.size(); i++)
{
if (i >= s.size() - 2)
{
ans += s[i];
continue;
}
if (pos[i])
{
ans += s[i];
ans += '.';
continue;
}
if (t[i] == 'V'&&!pos[i+1])
{
ans += s[i];
ans += '.';
continue;
}
ans += s[i];
}
cout << ans << "\n";
}
E. Romantic Glasses
Problem - E - Codeforces
其实就是找到一个连续子数组的奇位与偶位的元素和相同,那我们不妨将所有偶位元素ai设置为-ai,在遍历数组用前缀和记录,当当前前缀和的数字为0或者出现第二次,那么则出现了目标的连续子数组。
ll f[N];
void solve()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> f[i];
ll sum = 0;
map<ll,ll>v;
for (int i = 1; i <= n; i++)
{
f[i] *= ((i % 2) ? 1 : -1);
sum += f[i];
if (v[sum]||!sum)
{
cout << "YES\n";
return;
}
v[sum]++;
}
cout << "NO\n";
}
F. Greetings
Problem - F - Codeforces
其实就是排序+离散化+树状数组,利用树状数组求逆序对。
当我们对元素按照终点的编号大小按照从小到大排序后,单独将他们的起点编号设置为一个数组,我们发现这个数组的逆序对就是我们要的答案,但是n^2的求解肯定会超时,我们可以用分治或者树状数组去快速求解逆序对,由于本人对树状数组熟悉一些,下面演示的是树状数组求解的代码。
struct Node
{
ll s,e,id;
}e[N];
ll n;
ll a[N], rak[N];
ll lowbit(ll x)
{
return x & (-x);
}
bool cmp(Node a, Node b)
{
return a.e < b.e;
}
bool cmp1(Node a, Node b)
{
return a.s < b.s;
}
void add(ll pos)
{
for (int i = pos; i <= n; i += lowbit(i)) a[i] += 1;
}
ll ask(ll pos)
{
ll ans = 0;
for (int i = pos; i >= 1; i -= lowbit(i)) ans += a[i];
return ans;
}
void solve()
{
memset(a, 0, sizeof(a));
memset(rak, 0, sizeof(rak));
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> e[i].s >> e[i].e;
}
sort(e + 1, e + 1 + n, cmp);
for (int i = 1; i <= n; i++)
{
e[i].id = i;
}
sort(e + 1, e + 1 + n,cmp1);
for (int i = 1; i <= n; i++)
{
rak[e[i].id] = i;
}
ll ans = 0;
for (int i = 1; i <= n; i++)
{
ll pos = rak[i];
ans += ask(n) - ask(pos);
add(pos);
}
cout << ans << "\n";
}