前言 希望自己以后每次打完cf 都能写一篇博客总结一下 才能有提升
这一场爆0了 难受啊 感觉自己太菜了 还是要多练练啊 以后的cf每次都要参加
A. Split it!
题目大意 :就是给你一个字符串和一个数k 然后让你观察这个字符串是否存在k+1个非空字符串a1,a2…,ak+1
s=a1+a2+…+ak+ak+1+R(ak)+R(ak−1)+…+R(a1)。
这里+表示串联。我们将R(x)定义为反向字符串x。例如R(abcd)=dcba (来自百度翻译)
其实就是让你观察这是否是一个回文字符串 有一个中间字符串 不用找翻转的 就相当于这个ak+1的字符串为这个大字符串的中心 然后你可以把它看成是一个点 然后在往两边找回文字母的个数 当k等于0时一定输出YES 然后当这个字母个数会大于等于k时 输出YES 否则输出NO 就行了
一开始写的时候一直显示Wrong answer on test 2 人都快傻了 结束了都不知道为啥 后面看了一眼题解才知道 我理解的有点问题 对于这个中间的不用回文的字符串 找错了 我计算的时候一直以为 这个大字符串一定要满足回文的状态 否则直接输出NO
结果一直没发现它是错的
正确代码
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxt=110;
int t,n,k;
char h[maxt];
int main()
{
cin>>t;
while(t --){
cin>>n>>k;
cin>>h;
if(k==0) cout<<"YES"<<endl;
else {
int r=0;//中间的字符串是独立的不受影响 一旦不满足回文的时候直接退出循环就可以了
for(int i=0,j=n-1;j-i>1;i ++,j--){//在这里的判断条件设为j-i>1的时候很妙 就不用考虑字符串个数是奇数还是偶数了
if(h[i]==h[j]) r++;
else break;
}
if(r>=k) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
return 0;
}
B. Max and Mex
题目大意:给你S集合(非负数)中有n个数进行k次操作 每次从中得出两个数a=mex(S) b=max(S),mex(S)的意思就是在这个集合中没有出现过的最小数,max(S)的意思是这集合中最大的数
然后x=((a+b)/2) 将这个数加入到S集合中 最后再求这个集合中有多少个不同的元素。
题目意思还是蛮好理解的 就是不知道为啥我码的代码超时了 感觉是自己的思路有点问题
正确思路 :
可以分成三种情况
1.当k=0时 不用做操作 有n个不同元素
2.当k不等于0时 集合S中是0到n的全排列 最后是有k+n个不同元素
3.当k既不等于0也不是全排列时 找到x值判断这个值是否在这个集合中出现过 如果出现过 不管k是多少 最后都是有n个不同的元素 如果没有出现过 就是有n+1个不同的元素
思路理清了 还是挺简单的
正确代码
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxt = 100010;
int t, n, k;
int h[maxt];
int main()
{
cin >> t;
while (t--) {
cin >> n >> k;
for (int i = 0; i < n; i++) {
cin >> h[i];
}
sort(h, h + n);
int sum;
if (k == 0) sum = n;
else {
int x, y, res = 1;
for (int i = 0; i < n; i++) {
if (h[i] != i) {
x = i;
res = 0;
break;
}
}
if (res) sum = n + k;
else {
y = h[n - 1];
int a = (x + y) / 2;
if ((x + y) % 2 == 1) a++;
for (int i = 0; i < n; i++) {
if (a == h[i]) {
sum = n;
res = 1;
break;
}
}
if (res == 0) sum = n + 1;
}
}
cout << sum << endl;
}
return 0;
}
C. Diamond Miner
题目大意:题目意思还是很好理解的 这里就不多赘述了(其实是因为懒 “手打狗头”)
其实一开始如果不知道怎么写的话 可以用几个样例试一下就出来了 比如第2个样例 就很好
试了一下就会发现 当把每个离原点最近的点对应连起来这样的总距离是最小的 然后直接输出就行了
在这里要注意一个地方 输入要用scanf() 不然会出问题 别问为什么 问就是又在这里翻车了
以后再也不偷懒用cin了
#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxt = 100010;
int t, n;
double h[maxt], k[maxt];
double sum = 0;
int main()
{
cin >> t;
while (t--) {
cin >> n;
sum = 0;
int a=0,b=0;
double x,y;
for (int i = 1; i <= n * 2; i++) {
scanf("%lf %lf",&x,&y);
if (x == 0) h[a++] = y * y;
else k[b++] = x * x;
}
sort(h, h + n);
sort(k, k + n);
for (int i = 0; i < n; i++) {
sum += sqrt(h[i] + k[i]);
}
printf("%.15lf\n", sum);//这里其实保留10位小数就可以 题目要求了 误差不超过10的-9次方就可以
}
return 0;
}
希望自己以后可以坚持下去
能力有限 先以三题为目标 以后如果能力允许的话希望可以多写几题
一起共勉