前言
很多题只是换了个问法,做法是共通的。
题目 A - Two Rabbits
链接: Two Rabbits
题意:
有两只兔子在向着对方跳跃,高兔子在左边,矮兔子在右边,告诉两只兔子每秒的跳跃距离,请问两只兔子是否可以在某时刻同时跳到同一位置。
输入格式
每个测试包含一个或多个测试用例。第一行包含测试用例的数量t (1 ≤ t ≤ 1000)。
每个测试用例只包含一行。该行由四个整数组成x,y,a,b (0 < x <= y < 109,1 ≤ a,b ≤ 109) — 高大兔子的当前位置、较矮的兔子的当前位置、较高兔子的跳跃距离和较矮的兔子的跳跃距离。
输出格式
对于每个测试用例,打印单个整数:两只兔子处于同一位置所需的秒数。
如果两只兔子永远不会同时处于同一位置,请打印 -1
。
数据范围
1 ≤ t ≤ 103
0 < x <= y < 109
−100 ≤ ai ≤ 100
输入样例:
5
0 10 2 3
0 10 3 3
900000000 1000000000 1 9999999
1 2 1 1
1 3 1 1
输出样例:
2
-1
10
-1
1
思路:
- 思维 。小学数学,只要两只兔子起点的距离,是两者跳跃距离之和的整数倍,就代表两只兔子可以相遇。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e2+50;
const int M=2e4+10;
typedef long long ll;
int a[N];
int f[M];//达到价值i最少要f[i]枚硬币
int main()
{
int n;
cin>>n;
while(n--)
{
ll x,y,a,b;
cin>>x>>y>>a>>b;//起点,终点,a b
if((y-x)%(a+b)==0)cout<<(y-x)/(a+b)<<endl;
else cout<<-1<<endl;
}
system("pause");
return 0;
}
题目 B - Longest Palindrome
题目:Longest Palindrome
题意:
给我们n个长度为m的字符串,可以删除任意个字符串,然后以任意顺序重新排序,如果可以得到一个回文串,打印以此法得到的最长回文串的长度以及该回文串。
输入格式
第一行包含两个整数n和m (1 ≤ n ≤ 100,1 ≤ m ≤ 50) — 字符串的数量和每个字符串的长度。
下一个n行包含一串长度m每个,仅由小写拉丁字母组成。所有字符串都是 不同的 。
输出格式
在第一行中,打印您制作的最长回文字符串的长度。
在第二行中,打印回文。如果有多个答案,请打印其中任何一个。如果回文为空,请打印空行或根本不打印此行。
数据范围
1 ≤ n ≤ 100
1 ≤ m ≤ 50
输入样例:
3 3
tab
one
bat
输出样例:
6
tabbat
思路:
- 由于我们无法改变字符串内部字母的顺序,所以要想组成回文,必须找到另一个相反的字符串。对于自身就是回文的字符串,如果可以找到另一个和该串相同的字符串,就把这两个串当做前一种情况处理。对于只出现过一次回文串,找到最长的一个放到我们组成的回文串的中间,这样所组成的回文串就是最长的。
- 由于可以任意排序,所以回文串可能不唯一。那么我们在将找到对应回文串的字符串加入到最后的字符串中时就不必在意顺序。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e2+50;
const int M=2e4+10;
typedef long long ll;
int main()
{
int n,m;
cin>>n>>m;
unordered_map<string,int> p;
int cnt=0, mm=0;
string u,ans;
for(int i=1;i<=n;++i)
{
string s;
cin>>s;
string t=s;
reverse(s.begin(),s.end());
if(p[t]==1)
{
cnt+=s.size();
ans+=s;
}
else if(t==s)
{
if(t.size()>mm)
{
mm=t.size();
u=t;
}
}
p[s]++;
}
cout<<mm+cnt*2<<endl;
if(mm+cnt>0)
{
cout<<ans;
reverse(ans.begin(),ans.end());
if(mm>0)cout<<u;
cout<<ans<<endl;
}
system("pause");
return 0;
}
题目 C - Air Conditioner
题目:Air Conditioner
题意:
我们的店内有一个空调,该空调有三种状态:关闭,降温,升温。关闭状态下店内温度不变,降温状态店内每分钟下降一度,升温状态每分钟上升一度。我们要迎接n位顾客,店内初始温度是m,每位顾客有自己的满足温度区间,是否可以让所有顾客满意?
输入格式
每个测试包含一个或多个测试用例。第一行包含测试用例的数量q (1 ≤ q ≤ 500)。测试用例的说明如下。
每个测试用例的第一行包含两个整数n和m (1 ≤ n ≤ 100, −109 ≤ m ≤ 109),其中n是保留的客户数量,并且m是餐厅的初始温度。
接着,n行紧随其后。第i包含三个整数ti , li 和 hi (1 <= ti <=109 ,-109 <= li ,hi <= 109 ),其中 ti 是客户访问时间,li是其首选温度范围的下限,以及hi是其首选温度范围的上限。首选温度范围包括在内。
客户以访问时间的非递减顺序给出,当前时间为0。
输出格式
对于每个测试用例,如果可以满足所有客户,请打印“YES”。否则,请打印“NO”。
您可以打印任何大小写(大写或小写)的每个字母。
数据范围
1 ≤ n ≤ 105
0 ≤ ai ≤ 109
输入样例:
4
3 0
5 1 2
7 3 5
10 -1 0
2 12
5 7 10
10 16 20
3 -100
100 0 0
100 -50 50
200 100 100
1 100
99 -100 0
输出样例:
YES
NO
YES
NO
思路:
- 区间 。首先我们考虑是否能满足第一位顾客,只需要看是否能在他到达店里之前将温度控制到他满意的温度。而如果我们确定了第一位顾客离开的温度,后续n-1位顾客都可以按此方式判断是否可以满足。于是我们发现难点就在于如何在一位顾客离开后,确定此时的温度。
- 仔细想想就会发现这是无法做到的,因为每个顾客的满意温度是个区间,当前温度只要在这个区间中就可以。那么我们可以考虑是否可以维护一个区间,每次在两位顾客的间隙调整区间值,然后只需要判断所维护区间与下一位顾客的满意区间是否有重叠,如果有说明能够满足,否则不能满足。
- 如何在一位顾客离开后维护区间?我们只需要将所维护区间调整为与顾客满意区间重合部分就可以,因为如果顾客满意,那么顾客离开时,店内温度一定是处于顾客满意区间内的。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e2+50;
const int M=2e4+10;
typedef long long ll;
//每次维护一个区间,如果新的区间和所能达到的区间有重合,说明可以满足该顾客
bool judge(int l,int r,int a,int b)
{
if(a>=l&&a<=r||l>=a&&l<=b)return true;
return false;
}
int main()
{
int p;
cin>>p;
while(p--)
{
ll n,m;
cin>>n>>m;
ll l=m,r=m,tt=0;
bool flag=true;
for(int i=1;i<=n;++i)
{
ll t,a,b;
cin>>t>>a>>b;
int c=t-tt;
l-=c,r+=c;
if(l>b||r<a)flag=false;
else
{
if(l<a)l=a;
if(r>b)r=b;
}
tt=t;
}
flag?cout<<"YES"<<endl:cout<<"NO"<<endl;
}
system("pause");
return 0;
}