Codeforces Round #750 (Div. 2)

A. Luntik and Concerts

思路分析:

  • 首先我们可以肯定的是a,b,c都大于等于1,所以我们先让它们自己抵消自己,最后a,c只有三种情况。
  • a = 1, c = 1 如果只有奇数个b,我们取一个b * 2 + a抵消c,否则就拿两个b放到一个数组,另外一个放1个a,1个c。
  • a = 0, c = 1 不能抵消。
  • a = 0, c = 0 如果是偶数个b,那么我们把b分成两份,否则,我们就先取出一个b和一对a,c抵消,剩下的就和a = 1, c = 1,b为偶数一样了。

代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
ll t;
cin >> t;
while (t--)
{
ll a, b, c;
cin >> a >> b >> c;
a %= 2;
c %= 2;
if (a == 0 && c == 0 || (a == 1 && c == 1))
{
cout << 0 << endl;
}
else
cout << 1 << endl;
}
return 0;
}

B. Luntik and Subsequences

思路分析:

  • 考虑1和0这两个元素,如果有n个0的话我们对于每个0都有选与不选,所以答案就是\(2^n\),如果有m个1的话我们至少要选一个1,答案就是\(C_m^1\),乘法即可。

代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 100;
int a[maxn];
map<ll, ll> cnt;
ll qpow(ll a, ll b)
{
ll ans = 1;
while (b)
{
if (b & 1)
ans = ans * a;
a = a * a;
b >>= 1;
}
return ans;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
cnt.clear();
long long sum = 0;
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
sum += a[i];
cnt[a[i]]++;
}
cout << cnt[1] * qpow(2ll, cnt[0]) << endl;
}
return 0;
}

C. Grandma Capa Knits a Scarf

思路分析:

  • 首先我们肯定的是要删去的字符肯定是首次出现的不对称的两个字符(如果是其他的那么在第一个位置就不对称了)。
  • 然后就是如何求删除次数,我在这里采用的是双指针做法,一个在最左段,一个在最右段,如果相等,那么就指针移动,否则就删去和当前字符一样的字符,如果两端都不是当前字符,那么不可能回文,注意删去之后指针的移动即可。

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
char s[maxn];
int main()
{
int t;
cin >> t;
while (t--)
{
int n;
scanf("%d", &n);
scanf("%s", s + 1);
int ans = 0x3f3f3f3f;
int l = 1, r = n;
char ch[3];
int cnt = 0;
while (l < r)
{
if (s[l] == s[r])
{
l++;
r--;
}
else
{
ch[++cnt] = s[l];
ch[++cnt] = s[r];
break;
}
}
for (int i = 1; i <= 2; i++)
{
char c = ch[i];
int l = 1, r = n;
bool flag = 1;
int cnt = 0;
while (l < r)
{
if (s[l] == s[r])
{
l++;
r--;
}
else if (s[l] == c)
{
l++;
cnt++;
}
else if (s[r] == c)
{
r--;
cnt++;
}
else
{
flag = 0;
break;
}
}
if (flag)
{
ans = min(ans, cnt);
}
}
if (ans == 0x3f3f3f3f)
cout << -1 << endl;
else
cout << ans << endl;
}
return 0;
}

D. Vupsen, Pupsen and 0

思路分析:

  • 题目要求的是\(\sum_{i = 1}^n{a_i\times b_i} = 0\),我们可以这样想,我们把两个数两两匹配例如:\(a_i = 5, a_{i+1} = 4\) 我们就可以令\(b_i = 4, b_{i+1} = -5\),依次类推。
  • 那么每次都能两两匹配的话\(n\)必须是偶数,所以还要讨论\(n\)为奇数的时候,我们可以直接把前三项取出来,让这三项相加为\(0\),那么就有三种情况。

代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 10;
ll a[maxn];
ll sum;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
sum = 0;
ll n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
sum += a[i];
}
if (n % 2 == 0)
{
for (int i = 1; i <= n; i += 2)
{
cout << a[i + 1] << ' ' << -a[i] << ' ';
}
cout << endl;
}
else if (n % 2 == 1)
{
//不可能三项加起来都为0,所以保证了有答案
//推一下就好了
if (a[3] + a[1] != 0)
cout << a[2] << ' ' << -(a[3] + a[1]) << ' ' << a[2] << ' ';
else if (a[1] + a[2] != 0)
{
cout << a[3] << ' ' << a[3] << ' ' << -(a[2] + a[1]) << ' ';
}
else if (a[3] + a[2] != 0)
{
cout << -(a[2] + a[3]) << ' ' << a[1] << ' ' << a[1] << ' ';
}
for (int i = 4; i <= n; i += 2)
{
cout << a[i + 1] << ' ' << -a[i] << ' ';
}
cout << endl;
}
}
return 0;
}

F1. Korney Korneevich and XOR (easy version)

思路分析:

  • 考虑dp,dp[i]表示得到i这个数的子序列最后一位(递增子序列)的最小值,具体细节看代码注释。

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int dp[1001];
int a[maxn];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
memset(dp, 0x3f3f3f3f, sizeof(dp));
//先让dp[i]默认为最大
dp[0] = 0;
//dp[0] = 0;
for (int i = 1; i <= n; i++)
{
for (int j = 1000; j >= 0; j--)
{
//更新一下子序列最后一位的最小值
if (dp[j] < a[i])
{
dp[j ^ a[i]] = min(dp[j ^ a[i]], a[i]);
}
//只要子序列最后一位的最小值小于当前这个数就可以状态转移,因为保证子序列是递增的。
}
}
int cnt = 0;
for (int i = 0; i <= 1000; i++)
{
if (dp[i] != 0x3f3f3f3f)
cnt++;
}
cout << cnt << endl;
for (int i = 0; i <= 1000; i++)
{
if (dp[i] != 0x3f3f3f3f)
cout << i << ' ';
}
cout << endl;
return 0;
}

F2. Korney Korneevich and XOR (hard version)

思路分析:

  • 如果这题和上题一样的做法的话会T掉,所以要想一下另外一个算法。
  • 这里的dp值其实就是得到的异或值中的子序列中最后一个值的最先出现的位置。
  • 如果能加入到这个子序列的话,那么这个数必须要是在这个子序列中最后一个值出现的位置之后而且值小于它。

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1 << 13;
int f[maxn];
const int N = 1e6 + 7;
int main()
{
int n;
cin >> n;
vector<int> a(n + 1), g[5005];
for (int i = 1; i <= n; i++)
{
cin >> a[i];
g[a[i]].emplace_back(i);
}
for (int i = 1; i < maxn; i++)
{
f[i] = N;
}
for (int i = 1; i <= 5000; i++)
{
for (int j = 0; j < maxn; j++)
{
auto pos = upper_bound(g[i].begin(), g[i].end(), f[j]);
if (pos != g[i].end())
{
f[i ^ j] = min((*pos), f[i ^ j]);
}
}
}
vector<int> ans;
for (int i = 0; i < maxn; ++i)
if (f[i] != N)
ans.emplace_back(i);
cout << ans.size() << '\n';
for (auto i : ans)
cout << i << ' ';
return 0;
}

最新文章

  1. java 开发业务逻辑的思考(1)- 通知短信发送
  2. user agent stylesheet (浏览器默认样式)!
  3. RecyclerView 滑动检测 (上滑 up)(下滑 down)(顶部 top)(底部 bottom)
  4. Color国际青年公寓
  5. 面向对象设计Object Oriented Design
  6. 汇编之FS段寄存器
  7. FreeModbus Slave For AVR源代码 精简版2 【worldsing 笔记】
  8. CentOS 7 修改hostname
  9. ServiceProvider实现
  10. OpenJDK 阅读源代码 Java 实现字节流输入类
  11. Unity3D消息:消息传递函数
  12. sql表命名规范
  13. sysbench使用教程【转载】
  14. JSP的几种跳转方式的异同
  15. 【easy】Number of Segments in a String 字符串中的分段数量
  16. hdu 4300 Clairewd’s message(扩展kmp)
  17. Java Mongo 自定义序列化笔记
  18. this和引用变量的地址值是同一个---------new后面的是构造方法
  19. MemoryFile偷取安卓内存
  20. KeyPress 和KeyDown 、KeUp之间的区别

热门文章

  1. Linux - 安装 ant
  2. 为什么要设置GOROOT/GOPATH
  3. Java中int和short的转化
  4. 自制计算器 v1.1
  5. Vue3的其他属性和API函数
  6. dedecms织梦修改标题默认长度
  7. Shell系列(27)- 条件判断之两个整数比较
  8. Jmeter导出测试报告
  9. Appium和Selenium的区别和联系
  10. AngularJS的简单实用