原题链接:http://codeforces.com/contest/1155/problem/A
题意: 给你一个字符串,求出是否存在子字符串在倒转后能使字符串的字典序变小,可以的话输出“YES”和子字符串的范围,不可以则输出“NO”。
思路: 直接暴力遍历,只要存在两个相邻字符的顺序从大到小排序即符合,否则不符合。
Code(C++):
#include
using namespace std;
int main(){
int n; cin>>n;
string str;
cin>>str;
for(int i=0;i<n;i++){
if(str[i]<str[i-1]){
cout<<"YES"<<endl<<i<<" "<<i+1<<endl;
return 0;
}
}
cout<<"NO"<<endl;
return 0;
}
原题链接:http://codeforces.com/contest/1155/problem/B
题意: 给出一个数字序列(n>=11),有两个人任意删除数字,直到数字只剩下11位。如果删除后的数字串开头是8,那么就是第一个赢,输出“YES”;否则就是第二个人赢,输出“NO”。
思路: 从第一个数字开始找到第 n-10 个数字,如果8的数量大于非8的数量,则输出“YES”,否则输出“NO”。
注意:计算’8’的数量,要定义为char型,因为比较的是ASCII码值,所以不能直接定义为int型后直接比较。
Code(C++):
#include
using namespace std;
char a[100100];
int main(){
int n; cin>>n;
int sum1=0,sum2=0;
for(int i=1;i<=n;i++){
cin>>a[i];
if(i<=n-10){
if(a[i]=='8') sum1++;
else sum2++;
}
}
if(sum1>sum2)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
return 0;
}
原题链接: http://codeforces.com/contest/1155/problem/C
题意: 给你 n 个事件开始时间和m个闹钟,对于每个闹钟,你可以定义第一个闹钟开始响的时间 y,然后它会每隔 p 分钟响一下,问是否能提醒到这 n 个事件,如果能请随意输出一组第一个闹钟开始的时间y和选择的间隔时间所在的位置 i 。
思路: 可想而知 y 就是第一个事件开始时间 x[0],然后求出这 n 个事件的所有间隔时间,找出他们的最大公约数,最后判断这个数是否能在 m 个间隔时间里找到,或者存在他的因子。
Code(C++):
#include
#include
using namespace std;
typedef long long ll;
const int N=3e5+100;
ll x[N],p[N],dif[N];
/*
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
*/
int main(){
int n,m;
cin>>n>>m;
int k=1;
for(int i=1;i<=n;i++){
cin>>x[i];
if(i!=1)
dif[k++]=x[i]-x[i-1];
}
ll t=__gcd(dif[1],dif[2]);
for(int i=3;i<n;i++){
t=__gcd(t,dif[i]);
}
ll ans=0;
for(int i=1;i<=m;i++){
cin>>p[i];
if(t%p[i]==0 && t>=p[i]){
ans=i;
}
}
if(ans)
cout<<"YES"<<endl<<x[1]<<" "<<ans<<endl;
else
cout<<"NO"<<endl;
return 0;
}
原题链接: http://codeforces.com/contest/1155/problem/D
题意: n个数,可以选择某个区间的数乘x,也可以不选,求乘完后的最大连续子段和。
思路: 把整个序列分成三种情况来dp:
注意,dp[0]里面要与0比较,因为是求连续子段和,而不是求子序列,子序列有可能不连续。
Code(C++):
#include
using namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
ll dp[3];
int main(){
ll n,x;
cin>>n>>x;
ll ans=-inf,a;
for(int i=1;i<=n;i++){
cin>>a;
dp[0]=max(0ll,dp[0]+a); //dp[0]表示没有乘过x的子序列的最大值,由于是连续子段,所以要与0比较
dp[1]=max(dp[0],dp[1]+a*x); //dp[1]表示正在乘x的子序列的最大值
dp[2]=max(dp[1],dp[2]+a); //dp[2]表示已经乘完x的子序列的最大值
ans=max(ans,dp[2]);
}
cout<<ans<<endl;
return 0;
}