BNUZ[2021-3-5]BNUZ套题比赛div3
A - Dense Array CodeForces - 1490A思路:这个东西,a[i],a[i+1]中的较大值除较小值要小于或者等于2才行,如果说较大值除较小值大于2,那么就插入一个数字,插入的数字是较小数的2倍(最好,但是不一定),同时计数器+1,直到这个最大值除最小值的比值大于2.#include<iostream>using namespace std;int min(in
A - Dense Array CodeForces - 1490A
思路:
这个东西,a[i],a[i+1]中的较大值除较小值要小于或者等于2才行,如果说较大值除较小值大于2,那么就插入一个数字,插入的数字是较小数的2倍(最好,但是不一定),同时计数器+1,直到这个最大值除最小值的比值大于2.
#include<iostream>
using namespace std;
int min(int a, int b)
{
return a < b ? a : b;
}
int max(int a, int b)
{
return a > b ? a : b;
}
int main() {
int i, j, pos, n, t, ans;
cin >> t;
while (t--) {
ans = 0;
int a[1000];
cin >> n;
for (i = 0; i < n; i++) cin >> a[i];
for (i = 0; i < n-1; i++) {
pos = 0;
int min1 = min(a[i], a[i + 1]);
int max1 = max(a[i], a[i + 1]);
while (min1 * 2 < max1) {
min1 *= 2;
pos++;
if (min1 >= max1)break;
}
ans += pos;
}
cout << ans << endl;
}
return 0;
}
B - Balanced Remainders CodeForces - 1490B
当时看不懂英文翻译,就没想这道题,看了题解还是蛮简单的。
就是一个数组中的元素,统计除以3以后0的余数,1的余数,2的余数,要操作多少次才能让他们相等。
#include<iostream>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
int i, a, n, ans = 0;
cin >> n;
int y0 = 0, y1 = 0, y2 = 0;
for (i = 0; i < n; i++) {
cin >> a;
if (a % 3 == 0)y0++;
else if (a % 3 == 1)y1++;
else if (a % 3 == 2)y2++;
}
while (!(y0 == y1 && y0 == y2 && y2 == y1))
{
ans++;
if (y0 > y1) { y0--; y1++; }
else if (y1 > y2) { y1--; y2++; }
else if (y2 > y0) { y2--; y0++; }
}
cout << ans << endl;
}
}
C - Favorite Sequence CodeForces - 1462A
思路:
这道水题我啪的一下很快嗷,就写出来了,first blood啊,这道题就是双指针嘛,一个指向开头,一个指向末尾,然后开头的指针不断往后面移动,末尾的指针不断往前移动。
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
int i, n, a[10000];
cin >> n;
for (i = 0; i < n; i++) {
cin >> a[i];
}
int k1 = 0, k2 = n - 1;
for (; k1 <= k2;) {
cout << a[k1++] << " ";
if (k1 > k2)break;
cout << a[k2--] << " ";
}
cout << endl;
}
}
D - Last Year’s Substring
思路:
这道题看上去很简单,但是蛮难想出来的。。花了很多时间才搞出来,有点像滑动窗口。这个窗口只需4个字符(“2020”)。前面的字符串s1维护窗口的前端,后面的字符串s2维护窗口的后端。如果拼在一起是2020的话,那就打印YES。如果移动了前面4个字符都不能满足要求,那就打印NO.
#include <iostream>
#include<cstring>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int i, n,flag=1;
cin >> n;
string a;
cin >> a;
for (i = 0; i < 5; i++) {
string s1 = a.substr(0, i);
string s2 = a.substr(n-4+i,4-i);
if (s1 + s2 == "2020") {
flag = 0;
cout << "YES" << endl;
break;
}
}
if(flag)cout << "NO" << endl;
}
}
E - Unique Number CodeForces - 1462C
这道题我用了好久去想,我想出两个方法:
方法1:DFS的全排列
方法2:巧解
方法1:但是错了,由于我的DFS技术太烂,不知道还能怎么减枝了。。我这个算法的特色就是一直搜索到底,然后求每一个最后的节点的最小值。虽然能跑出正确的结果,但是用膝盖想想就很费时间.下面给出大家一段TLE的代码:
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
int a[20], v[20],n,f,min1=1e10,z;
void dfs(int step, int sum)
{
int i;
if (step > 9 ||sum > n) { return; }
if (sum == n) {
f = 1;
for (i = 0; i < step; i++) {
z += a[i] * pow(10,i);
}
if (z < min1) { min1 = z; }
z = 0;
return;
}
for (i = 1; i <= 9; i++) {
if (!v[i]) {
a[step] = i;
v[i] = 1;
dfs(step + 1, sum + i);
v[i] = 0;
}
}
}
int main()
{
int t;
cin >> t;
while (t--)
{
f = 0;
cin >> n;
dfs(0, 0);
if (f)cout << min1 << endl;
else cout << -1 << endl;
memset(a, 0, sizeof(a));
memset(v, 0, sizeof(v));
min1 = 1e10;
z = 0;
}
}
方法二:
思路:回宿舍的时候想出来的一个很妙的方法,众所周知1+2+3+…+9=45,那么小于45的都是有答案的,而且这些书都是递增的,比如说17->189,18->289,那么我们完全可以用一个循环把他给他搞出来,代码如下:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
int a[100], k = 0;
memset(a, 0, sizeof(a));
int i,n;
cin >> n;
if (n > 45) { cout << -1 << endl; continue; }
for (i = 9;n-i>0; i--) {
a[k] = i;
k++;
n -= i;
}
cout << n;
for (i = k-1; i >= 0; i--) {
cout << a[i];
}
cout << endl;
}
}
非常NICE
更多推荐
所有评论(0)