一、一元三次方程
1、题目:
有形如:ax2+bx2+ cx + d =0这样的一个一元三次方程。给出该方程中各项的系数( a , b , c , d 均为实数),并约定该方程存在三个不同实根(根的范围在﹣100至100之间),且根与根之差的绝对值≥1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位。
提示:记方程 f ( x )=0,若存在2个数x1和x2,且x1<x2, f (x1) xf (x2)<0,则在(x1,x2)之间一定有一个根。
输入描述
输入一行,4个实数 a , b , c , d
输出描述
输出一行,3个实根,从小到大输出,并精确到小数点后2位
2、代码:
#include <bits/stdc++.h>
using namespace std;
double a,b,c,d;
double f(double x){
return a*x*x*x+b*x*x+c*x+d;
}
int main()
{
cin>>a>>b>>c>>d;
for(int i=-100;i<100;i++){
double left=i;
double right=i+1;
if(f(left)==0){
printf("%.2lf ",left);
}
else if(f(left)*f(right)<0){
while(right-left>0.01){
double middle=(left+right)/2;
if(f(left)*f(middle)<0){
right=middle;
}
else{
left=middle;
}
}
printf("%.2lf ",left);
}
}
return 0;
}
二、子串简写
1、题目:
程序猿圈子里正在流行一种很新的简写方法:对于一个字符串,只保留首尾字符,将首尾字符之间的所有字符用这部分的长度代替。例如 internation - alization 简写成i18n, Kubernetes (注意连字符不是字符串的一部分)简写成K8s, Lanqiao 简写成L5o等。
在本题中,我们规定长度大于等于 K 的字符串都可以采用这种简写方法(长度小于 K 的字符串不配使用这种简写)。
给定一个字符串 S 和两个字符c1和c2,请你计算 S 有多少个以c1开头c2结尾的子串可以采用这种简写?
输入格式
第一行包含一个整数 K 。
第二行包含一个字符串 S 和两个字符c1和C2。
输出格式
一个整数代表答案
2、代码:
#include <bits/stdc++.h>
using namespace std;
const int N=5*1e5+10;
string s;
int k;
char c1,c2;
using namespace std;
int main()
{
cin>>k;
cin>>s>>c1>>c2;
vector<int>v;
int count=0;
for(int i=0;i<(int)s.size();i++){
if(s[i]==c1){
v.push_back(i);
}
if(s[i]==c2){
if(i+1-k<0||!v.size()){
continue;
}
int l=0;
int r=v.size()-1;
while(l<r){
int middle=(l+r+1)/2;
if(i-v[middle]+1>=k){
l=middle;
}
else{
r=middle-1;
}
}
if(i-v[l]+1>=k){
count+=(l+1);
}
}
}
cout<<count;
return 0;
}
三、管道
1、题目:
一开始管道是空的,位于L2的阀门会在 S ;时刻打开,并不断让水流入管道。对于位于 Li 的阀门,它流入的水在 T ;( T ;≥ Si )时刻会使得从第 Li -( T :- Si )段到第 Li +( T ;- S ;)段的传感器检测到水流。求管道中每一段中间的传感器都检测到有水流的最早时间。输入的第一行包含两个整数 n , len ,用一个空格分隔,分别表示会打开的阀门数和管道长度。
输入格式:
第 Li 段管道中央的阀门会在 S ;时刻打开。接下来 n 行每行包含两个整数 Li , Si ,用一个空格分隔,表示位于Li段管道中央的阀门会在Si时刻打开。
输出格式
输出一行包含一个整数表示答案。
2、代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 10;
const int LEN=1e9;
long long L[N];
long long S[N];
int n, len;
int check(int x) {
int count = 0;
int last_l = 2, last_r = 1;
for (int i = 0; i < n; i++) {
if (x >=S[i]) {
count++;
int left = L[i] - (x -S[i]);
int right=L[i]+(x-S[i]);
if(last_l>left){
last_l=left;
last_r=max(last_r,right);
}
else if(left<=last_r+1){
last_r=max(last_r,right);
}
}
}
if(count==0){
return false;
}
if(last_l<=1&&last_r>=len){
return true;
}
else{
return false;
}
}
signed main()
{
cin >> n >> len;
for (int i = 0; i < n; i++) {
cin >> L[i] >> S[i];
}
int l = 0;
int r = 2 * 1e9;
while (l < r) {
int middle = (l + r) / 2;
if (check(middle)) {
r = middle;
}
else {
l = middle + 1;
}
}
cout << l;
return 0;
}