【小结】:
很久没有打CF了,今天开始每次CF都不能放过了,因为自己本来自身实力就不足了,
如果再不努力就真的不行了,所以任何阻力也都是自己找的借口罢了(flag)。
昨晚真的早点回去宿舍,有两个题都是1A的,然后,第三题都是早上一做就出来了。
自己本来就不聪明,要是再不努力,真的神仙都救我不了。
什么课程,什么4级,什么期末考试,什么帮老师干活,现在在我看来也就是走形式罢了,
把全部精力都投入到 刷题上面去,身边不是缺乏例子,自己虽然没有胡浩那样有定力在网吧里刷题,
但我总不能把时间投入到皇室战争吧。
A. Minimizing the String
You are given a string ss consisting of nn lowercase Latin letters.
You have to remove at most one (i.e. zero or one) character of this string in such a way that the string you obtain will be lexicographically smallest among all strings that can be obtained using this operation.
String s=s1s2…sns=s1s2…sn is lexicographically smaller than string t=t1t2…tmt=t1t2…tm if n<mn<m and s1=t1,s2=t2,…,sn=tns1=t1,s2=t2,…,sn=tn or there exists a number pp such that p≤min(n,m)p≤min(n,m) and s1=t1,s2=t2,…,sp−1=tp−1s1=t1,s2=t2,…,sp−1=tp−1 and sp<tpsp<tp .
For example, "aaa" is smaller than "aaaa", "abb" is smaller than "abc", "pqr" is smaller than "z".
Input
The first line of the input contains one integer nn (2≤n≤2⋅1052≤n≤2⋅105 ) — the length of ss .
The second line of the input contains exactly nn lowercase Latin letters — the string ss .
Output
Print one string — the smallest possible lexicographically string that can be obtained by removing at most one character from the string ss .
Examples
Input
3
aaa
Output
aa
Input
5
abcda
Output
abca
Note
In the first example you can remove any character of ss to obtain the string "aa".
In the second example "abca" < "abcd" < "abcda" < "abda" < "acda" < "bcda".
【题解】:
分两个情况即可;
1、如果非严格递增的,就是 aaaaa或者abcdddd。删去最后一个即可
2、如果出现有下降的,比如abcda那就删除下降的前一个。
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+1000;
char s[N];
int main()
{
int n,i,j;
scanf("%d%s",&n,s);
for(i=1;i<n;i++){
if(s[0]!=s[i])
break;
}
if(i==n){
printf("%s",s+1);
}else{
for(i=1;i<n;i++){
if(s[i]<s[i-1]){
for(j=i;j<=n;j++){
s[j-1]=s[j];
}
break;
}
}
if(i==n)
s[n-1]='\0';
printf("%s",s);
}
return 0;
}
B. Divisor Subtraction
You are given an integer number nn. The following algorithm is applied to it:
- if n=0n=0, then end algorithm;
- find the smallest prime divisor dd of nn;
- subtract dd from nn and go to step 11.
Determine the number of subtrations the algorithm will make.
Input
The only line contains a single integer nn (2≤n≤10102≤n≤1010).
Output
Print a single integer — the number of subtractions the algorithm will make.
Input
5
Output
1
Input
4
Output
2
Note
In the first example 55 is the smallest prime divisor, thus it gets subtracted right away to make a 00.
In the second example 22 is the smallest prime divisor at both steps.
【题解】:
纯属翻译加看结论:
翻译为:
1、如果是n==0, 则跳出。
2、找到当前n 的最小质因数d。
然后n=n-d;
3、返回第一步。
好几个学长都翻译错了,
其实这个题很好看出来,如果是偶数,
直接答案就是n/2;
如果本身是素数,那么答案就是1
其他情况就是,先暴力找出最小的质因数d,
然后 答案就是:1+n-d)/2
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+1000;
typedef long long ll;
char s[N];
int main()
{
ll n,i,ans=0,flag=1;
cin>>n;
if(n&1){
for(i=2;i*i<=n;i++){
if(n%i==0){
ans++;
n-=i;flag=0;
break;
}
}
if(flag){
return 0*printf("1\n");
}
}
ans+=n/2;
cout<<ans<<endl;
return 0;
}
C. Meme Problem
Try guessing the statement from this picture:
You are given a non-negative integer dd . You have to find two non-negative real numbers aa and bb such that a+b=da+b=d and a⋅b=da⋅b=d .
Input
The first line contains tt (1≤t≤1031≤t≤103 ) — the number of test cases.
Each test case contains one integer dd (0≤d≤103)(0≤d≤103) .
Output
For each test print one line.
If there is an answer for the ii -th test, print "Y", and then the numbers aa and bb .
If there is no answer for the ii -th test, print "N".
Your answer will be considered correct if |(a+b)−a⋅b|≤10−6|(a+b)−a⋅b|≤10−6 and |(a+b)−d|≤10−6|(a+b)−d|≤10−6 .
Input
7
69
0
1
4
5
999
1000
Output
Y 67.985071301 1.014928699
Y 0.000000000 0.000000000
N
Y 2.000000000 2.000000000
Y 3.618033989 1.381966011
Y 997.998996990 1.001003010
Y 998.998997995 1.001002005
【题解】:
这个题非常简单,就是找一个a,b,使得他们相加和相乘都等于同一个数,
那么我们就用二分。
因为处理这类查找问题,加上精度的,通常都是二分,没有意外。
我们怎么确定标准呢,其实很简单,看事例,我们看出来了,通常都是一个 非常靠近n的一个数,再乘以1.*****这样的,
我就想到二分可以写了,
如果x*y>n 那么L=mid+eps,因为如果相差太远就会比他大,应该要靠近n。
如果x*y<=n 那么 R=mid-eps ,因为如果靠得太近会出现 0.00000**这样才会小,
最后求解出来的是不是答案呢,那么就需要 用我们的解去验证,代入即可。让他们的差距在1e-6内即可。
#include<bits/stdc++.h>
using namespace std;
const double eps=1e-10;
double d;
bool check(double x){
double y=d-x;
if(x*y>d){
return true;
}else{
return false;
}
}
int main()
{
int T;
cin>>T;
while(T--){
cin>>d;
if(d==4){
printf("Y %.9f %.9f\n",2.0,2.0);
continue;
}
double L=0,R=d,mid;
while(L<=R){
mid=(L+R)/2;
if(check(mid)){
L=mid+eps;
}else{
R=mid-eps;
}
}
double t1=L,t2=d-L;
if(fabs(t1*t2-d)<1e-6){
t1=max(L,d-L);
t2=d-t1;
printf("Y %.9f %.9f\n",t1,t2);
}else{
printf("N\n");
}
}
return 0;
}
【题解】:
听说学长看到别人的做法居然是解方程组,后来我就看出来了。
这居然是我高中的知识点,却忘记了,韦达定理。
x1 + x2 =-b/a
x1 * x2 = c/a
当前 x1+x2=d, x1*x2=d
令a=1,
那么就是求解一个一元二次方程罢了。
这个方程的形式是:
x^2-dx+d=0
首先判断有没有解,用delta = b^2 - 4ac = d^2-4d >= 0
然后两个解分别为: x1=(d+sqrt(d*d-4d ))/2 . x2=(d-sqrt(d*d-4d ))/2
然后输出即可:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--){
double d;
scanf("%lf",&d);
double delta=d*d-4*d;
if(delta>=0){
printf("Y ");
}else{
printf("N\n");
continue;
}
double t1=(d+sqrt(d*d-4*d))/2;
double t2=(d-sqrt(d*d-4*d))/2;
printf("%.9f %.9f\n",t1,t2);
}
return 0;
}