A. Do Not Be Distracted!
题目大意
给定一个字符串,判断是否有某个字符不连续的出现过两次及以上,如果有,输出"NO",否则输出"YES"。
解题思路
直接遍历一遍,用map标记那些字符已经出现过,同时用一个标记来记录当前的字符是哪个即可。
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdio>
#include<set>
#include<stack>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int N = 2e5 + 100;
char s[200];
int main(){
int t;
cin >> t;
while(t--){
int n;
cin >> n;
cin >> s + 1;
map<char, bool> pp;
char tag = '0';
bool cann = 1;
for (int i = 1; i <= n;i++){
if(s[i]!=tag){
tag = s[i];
if(!pp[tag]){
pp[tag] = true;
}
else{
cann = 0;
}
}
}
if(cann){
cout << "YES" << endl;
}
else{
cout << "NO" << endl;
}
}
return 0;
}
B. Ordinary Numbers
题目大意
给定一个数 n ,输出从 1 到 n 中所有每一位数都相等的数的个数(如 111 ,222)
解题思路
观察可知 1~10之间有9个数,10 ~100之间有9个数,以此类推,可以推得答案。
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdio>
#include<set>
#include<stack>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int N = 2e5 + 100;
char s[200];
int main(){
int t;
cin >> t;
while(t--){
int n;
cin >> n;
if(n<10){
cout << n << endl;
continue;
}
int tag = n;
int dig = 0;
while(n){
dig++;
n /= 10;
}
int ans = 0;
for (int i = 1; i <= dig - 1;i++){
ans += 9;
}
ll tt = 0;
int tt1 = 1;
while(tt<=tag){
tt = 0;
for (int i = 0; i < dig;i++){
tt += tt1 * pow(10, i);
}
if(tt<=tag){
ans++;
tt1++;
}
else{
break;
}
}
cout << ans << endl;
}
return 0;
}
C. Not Adjacent Matrix
题目大意
给定一个n * n得矩阵,把1 ~ n2这些数不重复得填进去,要求每个格子与其相邻格子中数的差值的绝对值大于 1。
解题思路
观察已给样例,不妨就按照n=3时的答案,当n大于3时,将多出来的数按奇偶分开,补在原矩阵的最下一行与最右一列即可,注意题目条件,填充行从左到右按从小到大方式,那填充列从上到下按从大到小方式。
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdio>
#include<set>
#include<stack>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int N = 2e5 + 100;
int a[110][110];
int main(){
int t;
cin >> t;
a[1][1] = 2, a[1][2] = 9, a[1][3] = 7, a[2][1] = 4, a[2][2] = 6, a[2][3] = 3;
a[3][1] = 1, a[3][2] = 8, a[3][3] = 5;
int tag = 3;
for (int j = 4; j <= 100;j++){
int tot = tag * tag + 1;
int tot1 = j*j - 1;
for (int k = 1; k <= tag + 1;k++){
a[j][k] = tot;
tot += 2;
}
for (int k = 1; k <= tag;k++){
a[k][j] = tot1;
tot1 -= 2;
}
tag++;
}
while (t--)
{
int n;
cin >> n;
if (n == 1)
{
cout << 1 << endl;
continue;
}
if (n == 2)
{
cout << -1 << endl;
continue;
}
else{
for (int i = 1; i <= n;i++){
for (int j = 1; j <= n;j++){
cout << a[i][j] << ' ';
}
cout << endl;
}
}
}
return 0;
}
D. Same Differences
题目大意
给定一个长为 n 的数组 a,问有多少组(ai , aj)满足
i
<
j
a
j
−
a
i
=
j
−
i
i<j \\ a_j - a_i = j - i
i<jaj−ai=j−i
解题思路
将已给公式变换,可得
a
j
−
j
=
a
i
−
i
a_j - j=a_i-i
aj−j=ai−i
所以对数组的每个数进行这种操作,当满足条件时,将数目加到答案里,可在O(n)的复杂度内完成
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdio>
#include<stack>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int N = 2e5 + 100;
ll a[N];
int main(){
int t;
cin>>t;
while(t--){
map<int, int> pp;
ll ans = 0;
int n;
cin >> n;
for (int i = 1; i <= n;i++){
cin >> a[i];
int x = a[i] - i;
ans += pp[x];
++pp[x];
}
cout << ans << endl;
}
return 0;
}
E. Arranging The Sheep
题目大意
给定一个字符串 s 其中
∗
*
∗代表这里有一只羊,’.’ 代表这里是可以移动的空地,每次可以让一只羊向左边或右边的空地移动一次(必须有空地存在),问最少能做多少次操作,使得所有羊在一起,即
∗
*
∗连续。
解题思路
设羊总数为m只,那么由贪心的想法,每只羊的移动步数都要尽可能少,那么就令每只羊都往第 m/2 只羊的方向移动,计算总步数。
假如几只羊连续,那么把他们集体平移,每只羊的花费一样,都是两个区间之间空地的数目,所以只需要统计羊之间空地的数目即可。连续的羊可近似看作位于同一位置。
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdio>
#include<stack>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int N = 2e6 + 100;
char s[N];
int main(){
int t;
cin>>t;
while(t--){
int n;
cin >> n;
cin >> s + 1;
vector<int> ans;
int emp = 1;
for (int i = 1; i <= n;i++){
if(s[i]=='.'){
emp++;//统计空地数目
}
else{
ans.push_back(emp);//假如连续的羊,那么他们近似看作同一位置
}
}
ll outp = 0;
int mid = (ans.size()) / 2;
for (int i = 0; i < ans.size();i++){
outp += abs(ans[i] - ans[mid]);
}
cout << outp << endl;
}
return 0;
}
F1. Guess the K-th Zero (Easy version)
题目大意
此题题目较为复杂,首先给定一个 n 代表一个 01 序列的长度,给定一个 t,此题规定 t = 1,之后给定一个 k ,最后要求输出第 k 个 0 所在的位置,本题是一个交互题目, 后续的每一行先要求输出一个"? l r"代表一个对区间 l 到 r 的查询,下一行输入一个数,代表查询的结果,要求在少于20次操作内找到答案,以 "!x"的形式输出。
解题思路
比较明显的二分,二分查找所求答案的位置,由于此题的性质,不需要关心具体的序列与查询值,只要实现算法就行。
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdio>
#include<stack>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int N = 2e6 + 100;
char s[N];
int main(){
int n, t, k;
cin >> n >> t >> k;
int l = 1, r = n;
int tot = n;
while(l<r){
int mid = (l + r) / 2;
cout << "? 1 " << mid << endl;
int ans;
cin >> ans;
if(mid-ans>=k){
r = mid;
}
else{
l = mid + 1;
}
}
tot = l;
cout << "! " << tot << endl;
return 0;
}