A. Two Rabbits
#include<bits/stdc++.h>//数学
using namespace std;
int main(){
int t,time;
int x,y,a,b;
cin>>t;
while(t--){
cin>>x>>y>>a>>b;
if((y - x) % (a + b) == 0){
int k = (y - x) / (a + b);
cout<<k<<endl;
}
else cout<<"-1"<<endl;
}
return 0;
}//cf第一题 是个小学数学题
B. Longest Palindrome
#include<bits/stdc++.h>//字符串
using namespace std;
string arr[105]; //最开始的数组用来存储输入数据 用作对比
int main(){
set<string>term;//这里用一个set两个的vector的原因是 set集合自带find功能 这个集合存储输入的数据 用来查找
vector<string>left,right;//两个动态数组 分别存储回文的前后部分
int num,len;//num是字符串个数 len是长度
string mid;//mid是中间的回文字符串 如果输入数据中有多个回文字符串 在字符串确保distinct的前提下 直接覆盖
//这里也是我比赛的时候没有想通的 不可能有两个能够组成回文字符串并且自身也是回文字符串的字符串
cin>>num>>len;
for(int i = 1;i <= num;i++){
cin>>arr[i];
term.insert(arr[i]);//set的存储方式是insert
}
for(int i = 1;i <= num;i++){
string str = arr[i];//将这个元素赋值给str
reverse(str.begin(),str.end());//将str翻转
if(arr[i] == str)mid = str;//如果翻转前后结果一样 说明arr[i]自身是回文字符串
else if(term.find(str) != term.end()){//如果自身不是 并且在set里面找到了这个翻转之后的字符串
left.push_back(arr[i]);
right.push_back(str);
term.erase(arr[i]);
term.erase(str);//就把翻转前的字符串和翻转后的字符串分别存到两个动态数组里面 并且在set里面删除这两个元素
}
}
printf("%d\n",left.size() * len * 2 + mid.size());//输出即将输出的字符串的长度
for(string x : left)cout<<x;//for(int i = 0;i < left.size();i++)cout<<left[i];本来的写法
cout<<mid;
reverse(right.begin(),right.end());//这一步翻转了动态数组里面字符串的排列顺序 left里面第一个输出的在right里最后输出
for(string x : right)cout<<x;
return 0;
}//掌握了此题后 不难发现cf div2里的前三题不会涉及太难的算法 都是题意的理解与代码的优化 熟练运用stl并且寻找最优方法是解题关键
C. Air Conditioner
#include<stdio.h>//贪心 模拟
int timee[105],low[105],high[105];
int main(){
int n,num,t,Min,Max,flag = 0,count = 0,term;
scanf("%d",&n);
while(n--){
count = 0;
scanf("%d %d",&num,&t);
int tmax,tmin;
tmax = tmin = t;
for(int i = 1;i <= num;i++)scanf("%d %d %d",&timee[i],&low[i],&high[i]);
for(int i = 1;i <= num;i++){
term = timee[i];
if(i > 1)term = timee[i] - timee[i - 1];
Min = tmin - term;
Max = tmax + term;
if(Min > high[i])break;
if(Max < low[i])break;
tmin = low[i] > Min ? low[i] : Min;
tmax = high[i] < Max ? high[i] : Max;
count++;
}
if(count == num)printf("YES\n");
else printf("NO\n");
}
return 0;
}//c题我做了比较久的时间 代码一开始是RT 后来是WA 说明代码繁琐的同时核心代码有误
D. Shortest and Longest LIS
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 50;//这个最大值我也不知道为什么要设成题目中的字符串长度之和最大值
int n,num,arr[maxn],brr[maxn];//n是字符串长度(其实就是1-n这么多数字)两个数组分别存储最短LIS 最大LIS
string s;//工作字符串
int main(){
int t;
cin>>t;
while(t--){
cin>>n>>s;
num = n;//考虑最短LIS时大的数字(最大是n)是要优先放在前面的 所以这里的num赋值n
for(int i = 0;i < n;i++){
int len = 1;//len表示在LIS中出现连续小于号的次数加一
while(i < s.size() && s[i] == '<'){
len++;
i++;
}
for(int j = i;j > i - len;j--)arr[j] = num--;//这一步核心代码我现在也是没完全看懂 但是这么写是正确的
}
for(int i = 0;i < n;i++)cout<<arr[i]<<' ';
cout<<endl;
num = 1;//最大LIS的操作和之前的十分相似 但是大的数字是要优先放在后面 num赋初值1
for(int i = 0;i < n;i++){
int len = 1;
while(i < s.size() && s[i] == '>'){
len++;
i++;
}
for(int j = i;j > i - len;j--)brr[j] = num++;
}
for(int i = 0;i < n;i++)cout<<brr[i]<<' ';
cout<<endl;
}
return 0;
}