Codeforces Round #719 (Div. 3)
A. Do Not Be Distracted!
题目大意:
首先是T组数据,然后输入一个n代表字符串的长度,然后一个字符串,其实最后判断的就是,看有没有前面出现过的字符再后面又一次出现了
代码实现:
#include <bits/stdc++.h>
using namespace std;
set<char> a;
void solve()
{
a.clear();
int n;
scanf("%d", &n);
string s;
cin >> s;
a.insert(s[0]);
bool flag = true;
for (int i = 1; i < s.size(); i++)
if (s[i] != s[i - 1])
if (a.count(s[i]))
{
flag = false;
break;
}
else
a.insert(s[i]);
flag ? puts("YES") : puts("NO");
}
signed main()
{
int T;
scanf("%d", &T);
while (T--)
{
solve();
}
return 0;
}
B. Ordinary Numbers
题目大意:
首先是T组数据,然后给定一个数字n,让我们判断从1到n有多少个满足条件的数,条件为这个数字在十进制的表示中各个位置的数字相同,我们只要直接遍历满足情况的个数,我们可以发现每一个10的次方区间里都是9个,但是这里注意一点,中间变量记得开long long以防止炸掉
代码实现:
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve()
{
int n;
scanf("%lld", &n);
int ans = 0;
for (int i = 1; i <= 9; i++)
{
int temp = i;
while (temp <= n)
temp = temp * 10 + i, ans++;
}
printf("%lld\n", ans);
}
signed main()
{
int T;
scanf("%lld", &T);
while (T--)
{
solve();
}
return 0;
}
C. Not Adjacent Matrix
题目大意:
首先是T组数据,然后给你一个整数n,然后问你有没有这么一个矩阵可以满足如下条件,如果矩阵中的两个相邻,那么这两个矩阵块中的元素就是不能相邻的,如果有则输出这样的一个矩阵,否则输出-1,那么我们就可以开两个栈,一个用来存储奇数,一个用来存储偶数,然后我们先把奇数输出,再输出偶数,就可以保证相邻的一个单元格内没有相邻的元素
代码实现:
#include <bits/stdc++.h>
using namespace std;
stack<int> add, even;
void solve()
{
while (!add.empty())
add.pop();
while (!even.empty())
even.pop();
int n;
scanf("%d", &n);
if (n == 1)
puts("1");
else if (n == 2)
puts("-1");
else
{
for (int i = 1; i <= n * n; i++)
if (i & 1)
add.push(i);
else
even.push(i);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (!add.empty())
{
int temp = add.top();
printf("%d ", temp);
add.pop();
}
else
{
int temp = even.top();
printf("%d ", temp);
even.pop();
}
}
puts("");
}
}
}
signed main()
{
int T;
scanf("%d", &T);
while (T--)
{
solve();
}
return 0;
}
D. Same Differences
题目大意:
首先是T组数据,然后给定一个n,输入n个数字,然后询问这个数组里面,有多少个满足 i<j a[j]-a[i]=j-i 的组合,最后输出这个组合,这个我们可以对给定的这个式子进行化简,然后我们可以得到这么一个式子 a[j]-j = a[i]-i 我们只要判断有多少种情况满足这个数字减去它的下标的值的情况即可,这里我们要记得注意情况的最多数量,是从1累加到2e5所以这里我们存储数据时记得开long long
代码实现:
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int a[N], n;
map<int, int> mp;
void solve()
{
mp.clear();
memset(a, 0, sizeof(a));
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
long long ans = 0;
for (int i = 1; i <= n; i++)
{
ans += mp[a[i] - i];
mp[a[i] - i]++;
}
printf("%lld\n", ans);
}
signed main()
{
int T;
scanf("%d", &T);
while (T--)
{
solve();
}
return 0;
}
E. Arranging The Sheep
题目大意:
首先是T组数据,然后给定一个n,接下来是n个字符,我们要做的就是把这里面所有的*都挪到一起所需要的一个最小的步骤是多少,求出这个步骤即可
我们初步思路是找到最中心的那个那个星号的位置,然后我们让其他的星星向这个点靠近,我们猜测这个是最优解,然后我们证明这个猜想,这个思路很简单,中位数的一个思想,就是我们想这么一个问题如果是选择了其他的星号点,那么我其他地方向这个点移动的一个过程中,我中间肯定是会出现重复路径很多次,但是如果我选择的是中间的那个点,那么我们思考一下,他也会有重复的地方,但是这个重复的过程是最少的一种情况,所以我们大胆假设加猜测和样例的一个验证,最后我们得到这么一个结论,我们要寻找的就是最中间的那一个点,这个的具体证明是中位数定理
这里有中位数定理的一个简单的证明,和常用的情况中位数定理的一篇博客
代码实现:
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve()
{
int n;
scanf("%lld", &n);
string s;
cin >> s;
// cout << s << endl;
int sum = 0; //统计星号的数量
for (int i = 0; i < s.size(); i++)
if (s[i] == '*')
sum++; //统计了一共有多少个星号
if (sum == 1 || sum == 0)
puts("0");
else
{
// printf("sum=%d\n", sum);
int temp = (sum >> 1) + 1; //找中间的那个位置的星号
// printf("temp=%d\n", temp);
int pos = 0; //用于记录中间的那个星号的一个位置
for (int i = 0; i < s.size(); i++)
{
if (s[i] == '*')
pos++;
if (pos == temp)
{
pos = i;
break;
}
} //找到中间星号的位置
// printf("pos=%d\n", pos);
bool flag = true; //用于判断是在中间星号的左边还是右边
// true为左边,false为右边
int ans = 0, num = 0;
// ans记录的是最后的一个步数,然后num记录的是少走的步数
for (int i = 0; i < s.size(); i++)
{
if (s[i] == '*' && i != pos)
{
if (i < pos)
{
ans += pos - i - 1 - num;
num++;
}
else if (i > pos)
{
if (flag)
{
flag = false;
num = 0;
}
ans += i - pos - 1 - num;
num++;
}
}
}
printf("%lld\n", ans);
}
}
signed main()
{
// freopen("in.txt", "r", stdin);
int T;
scanf("%lld", &T);
while (T--)
{
solve();
}
return 0;
}
由于E题和F题是交互式问题,这个我不会,没有尝试过,所以这里不写记录了
G. To Go Or Not To Go?
由于本题对我这个菜鸡而言有点难,就划水过去了,以后回来再补